sonamu 0.7.4 → 0.7.5

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.
Files changed (133) hide show
  1. package/dist/api/config.d.ts +1 -4
  2. package/dist/api/config.d.ts.map +1 -1
  3. package/dist/api/config.js +1 -1
  4. package/dist/api/sonamu.d.ts +2 -0
  5. package/dist/api/sonamu.d.ts.map +1 -1
  6. package/dist/api/sonamu.js +19 -47
  7. package/dist/bin/cli.js +6 -6
  8. package/dist/database/base-model.d.ts +1 -1
  9. package/dist/database/base-model.d.ts.map +1 -1
  10. package/dist/database/base-model.js +15 -4
  11. package/dist/database/code-generator.d.ts.map +1 -1
  12. package/dist/database/code-generator.js +3 -3
  13. package/dist/database/db.d.ts.map +1 -1
  14. package/dist/database/db.js +1 -1
  15. package/dist/database/puri-wrapper.d.ts +11 -11
  16. package/dist/database/puri-wrapper.d.ts.map +1 -1
  17. package/dist/database/puri-wrapper.js +7 -11
  18. package/dist/database/puri.d.ts +36 -17
  19. package/dist/database/puri.d.ts.map +1 -1
  20. package/dist/database/puri.js +54 -7
  21. package/dist/database/puri.types.d.ts +54 -17
  22. package/dist/database/puri.types.d.ts.map +1 -1
  23. package/dist/database/puri.types.js +2 -4
  24. package/dist/database/puri.types.test-d.js +129 -0
  25. package/dist/database/upsert-builder.d.ts +16 -10
  26. package/dist/database/upsert-builder.d.ts.map +1 -1
  27. package/dist/database/upsert-builder.js +10 -19
  28. package/dist/entity/entity-manager.d.ts +113 -22
  29. package/dist/entity/entity-manager.d.ts.map +1 -1
  30. package/dist/entity/entity-manager.js +1 -1
  31. package/dist/entity/entity.d.ts +34 -0
  32. package/dist/entity/entity.d.ts.map +1 -1
  33. package/dist/entity/entity.js +110 -37
  34. package/dist/index.d.ts +5 -0
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +8 -2
  37. package/dist/migration/code-generation.d.ts.map +1 -1
  38. package/dist/migration/code-generation.js +341 -149
  39. package/dist/migration/migration-set.d.ts.map +1 -1
  40. package/dist/migration/migration-set.js +21 -5
  41. package/dist/migration/migrator.d.ts.map +1 -1
  42. package/dist/migration/migrator.js +7 -1
  43. package/dist/migration/postgresql-schema-reader.d.ts +11 -1
  44. package/dist/migration/postgresql-schema-reader.d.ts.map +1 -1
  45. package/dist/migration/postgresql-schema-reader.js +111 -10
  46. package/dist/syncer/syncer.d.ts.map +1 -1
  47. package/dist/syncer/syncer.js +4 -3
  48. package/dist/template/implementations/generated.template.d.ts.map +1 -1
  49. package/dist/template/implementations/generated.template.js +12 -2
  50. package/dist/template/implementations/generated_sso.template.d.ts +3 -3
  51. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
  52. package/dist/template/implementations/generated_sso.template.js +50 -2
  53. package/dist/template/implementations/model.template.js +6 -6
  54. package/dist/template/implementations/model_test.template.js +4 -4
  55. package/dist/template/implementations/view_enums_dropdown.template.js +2 -2
  56. package/dist/template/implementations/view_enums_select.template.js +2 -2
  57. package/dist/template/implementations/view_form.template.d.ts.map +1 -1
  58. package/dist/template/implementations/view_form.template.js +12 -9
  59. package/dist/template/implementations/view_id_async_select.template.js +4 -4
  60. package/dist/template/implementations/view_list.template.d.ts.map +1 -1
  61. package/dist/template/implementations/view_list.template.js +12 -9
  62. package/dist/template/implementations/view_search_input.template.js +2 -2
  63. package/dist/template/template.js +2 -2
  64. package/dist/template/zod-converter.d.ts.map +1 -1
  65. package/dist/template/zod-converter.js +17 -2
  66. package/dist/testing/fixture-manager.d.ts +2 -1
  67. package/dist/testing/fixture-manager.d.ts.map +1 -1
  68. package/dist/testing/fixture-manager.js +29 -29
  69. package/dist/types/types.d.ts +593 -68
  70. package/dist/types/types.d.ts.map +1 -1
  71. package/dist/types/types.js +113 -9
  72. package/dist/vector/chunking.d.ts +25 -0
  73. package/dist/vector/chunking.d.ts.map +1 -0
  74. package/dist/vector/chunking.js +97 -0
  75. package/dist/vector/config.d.ts +12 -0
  76. package/dist/vector/config.d.ts.map +1 -0
  77. package/dist/vector/config.js +83 -0
  78. package/dist/vector/embedding.d.ts +42 -0
  79. package/dist/vector/embedding.d.ts.map +1 -0
  80. package/dist/vector/embedding.js +147 -0
  81. package/dist/vector/types.d.ts +105 -0
  82. package/dist/vector/types.d.ts.map +1 -0
  83. package/dist/vector/types.js +5 -0
  84. package/dist/vector/vector-search.d.ts +47 -0
  85. package/dist/vector/vector-search.d.ts.map +1 -0
  86. package/dist/vector/vector-search.js +176 -0
  87. package/package.json +9 -8
  88. package/src/api/config.ts +0 -4
  89. package/src/api/sonamu.ts +21 -36
  90. package/src/bin/cli.ts +5 -5
  91. package/src/database/base-model.ts +20 -11
  92. package/src/database/code-generator.ts +6 -2
  93. package/src/database/db.ts +1 -0
  94. package/src/database/puri-wrapper.ts +22 -16
  95. package/src/database/puri.ts +150 -27
  96. package/src/database/puri.types.test-d.ts +457 -0
  97. package/src/database/puri.types.ts +231 -33
  98. package/src/database/upsert-builder.ts +43 -34
  99. package/src/entity/entity-manager.ts +2 -2
  100. package/src/entity/entity.ts +134 -44
  101. package/src/index.ts +6 -0
  102. package/src/migration/code-generation.ts +377 -174
  103. package/src/migration/migration-set.ts +22 -3
  104. package/src/migration/migrator.ts +6 -0
  105. package/src/migration/postgresql-schema-reader.ts +121 -21
  106. package/src/syncer/syncer.ts +3 -2
  107. package/src/template/implementations/generated.template.ts +51 -9
  108. package/src/template/implementations/generated_sso.template.ts +71 -2
  109. package/src/template/implementations/model.template.ts +5 -5
  110. package/src/template/implementations/model_test.template.ts +3 -3
  111. package/src/template/implementations/view_enums_dropdown.template.ts +1 -1
  112. package/src/template/implementations/view_enums_select.template.ts +1 -1
  113. package/src/template/implementations/view_form.template.ts +11 -8
  114. package/src/template/implementations/view_id_async_select.template.ts +3 -3
  115. package/src/template/implementations/view_list.template.ts +11 -8
  116. package/src/template/implementations/view_search_input.template.ts +1 -1
  117. package/src/template/template.ts +1 -1
  118. package/src/template/zod-converter.ts +20 -0
  119. package/src/testing/fixture-manager.ts +31 -30
  120. package/src/types/types.ts +226 -48
  121. package/src/vector/chunking.ts +115 -0
  122. package/src/vector/config.ts +68 -0
  123. package/src/vector/embedding.ts +193 -0
  124. package/src/vector/types.ts +122 -0
  125. package/src/vector/vector-search.ts +261 -0
  126. package/dist/template/implementations/view_enums_buttonset.template.d.ts +0 -17
  127. package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +0 -1
  128. package/dist/template/implementations/view_enums_buttonset.template.js +0 -31
  129. package/dist/template/implementations/view_list_columns.template.d.ts +0 -17
  130. package/dist/template/implementations/view_list_columns.template.d.ts.map +0 -1
  131. package/dist/template/implementations/view_list_columns.template.js +0 -49
  132. package/src/template/implementations/view_enums_buttonset.template.ts +0 -34
  133. package/src/template/implementations/view_list_columns.template.ts +0 -53
@@ -0,0 +1,97 @@
1
+ import { DEFAULT_VECTOR_CONFIG } from "./config.js";
2
+ /**
3
+ * 텍스트 청킹
4
+ * - 현재 가이드에서는 400토큰 이하만 저장하므로 기본적으로 사용하지 않음
5
+ * - 추후 긴 문서 처리 시 사용
6
+ */ export class Chunking {
7
+ config;
8
+ constructor(config = {}){
9
+ this.config = {
10
+ ...DEFAULT_VECTOR_CONFIG.chunking,
11
+ ...config
12
+ };
13
+ }
14
+ /**
15
+ * 텍스트를 청크로 분할
16
+ */ chunk(text) {
17
+ if (text.length < this.config.skipThreshold) {
18
+ return [
19
+ {
20
+ index: 0,
21
+ text: text.trim(),
22
+ startOffset: 0,
23
+ endOffset: text.length
24
+ }
25
+ ];
26
+ }
27
+ const chunks = [];
28
+ let currentPosition = 0;
29
+ while(currentPosition < text.length){
30
+ const remainingText = text.slice(currentPosition);
31
+ const { chunk, length } = this.extractChunk(remainingText);
32
+ if (chunk.trim().length >= this.config.minChunkSize) {
33
+ chunks.push({
34
+ index: chunks.length,
35
+ text: chunk.trim(),
36
+ startOffset: currentPosition,
37
+ endOffset: currentPosition + length
38
+ });
39
+ }
40
+ const advance = Math.max(length - this.config.chunkOverlap, this.config.minChunkSize);
41
+ currentPosition += advance;
42
+ }
43
+ return chunks;
44
+ }
45
+ /**
46
+ * 청킹이 필요한지 확인
47
+ */ needsChunking(text) {
48
+ return text.length > this.config.chunkSize;
49
+ }
50
+ /**
51
+ * 예상 청크 수 계산
52
+ */ estimateChunkCount(text) {
53
+ if (text.length <= this.config.chunkSize) {
54
+ return 1;
55
+ }
56
+ const effectiveChunkSize = this.config.chunkSize - this.config.chunkOverlap;
57
+ return Math.ceil(text.length / effectiveChunkSize);
58
+ }
59
+ extractChunk(text) {
60
+ if (text.length <= this.config.chunkSize) {
61
+ return {
62
+ chunk: text,
63
+ length: text.length
64
+ };
65
+ }
66
+ for (const separator of this.config.separators){
67
+ const result = this.splitBySeparator(text, separator);
68
+ if (result) return result;
69
+ }
70
+ return {
71
+ chunk: text.slice(0, this.config.chunkSize),
72
+ length: this.config.chunkSize
73
+ };
74
+ }
75
+ splitBySeparator(text, separator) {
76
+ const searchRange = text.slice(0, this.config.chunkSize + 100);
77
+ let lastIndex = -1;
78
+ let index = 0;
79
+ while(true){
80
+ index = searchRange.indexOf(separator, index);
81
+ if (index === -1) break;
82
+ if (index <= this.config.chunkSize) {
83
+ lastIndex = index + separator.length;
84
+ }
85
+ index++;
86
+ }
87
+ if (lastIndex > this.config.minChunkSize) {
88
+ return {
89
+ chunk: text.slice(0, lastIndex),
90
+ length: lastIndex
91
+ };
92
+ }
93
+ return null;
94
+ }
95
+ }
96
+
97
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92ZWN0b3IvY2h1bmtpbmcudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgREVGQVVMVF9WRUNUT1JfQ09ORklHIH0gZnJvbSBcIi4vY29uZmlnXCI7XG5pbXBvcnQgdHlwZSB7IENodW5rLCBDaHVua2luZ0NvbmZpZyB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICog7YWN7Iqk7Yq4IOyyre2CuVxuICogLSDtmITsnqwg6rCA7J2065Oc7JeQ7ISc64qUIDQwMO2GoO2BsCDsnbTtlZjrp4wg7KCA7J6l7ZWY66+A66GcIOq4sOuzuOyggeycvOuhnCDsgqzsmqntlZjsp4Ag7JWK7J2MXG4gKiAtIOy2lO2bhCDquLQg66y47IScIOyymOumrCDsi5wg7IKs7JqpXG4gKi9cbmV4cG9ydCBjbGFzcyBDaHVua2luZyB7XG4gIHByaXZhdGUgY29uZmlnOiBDaHVua2luZ0NvbmZpZztcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IFBhcnRpYWw8Q2h1bmtpbmdDb25maWc+ID0ge30pIHtcbiAgICB0aGlzLmNvbmZpZyA9IHsgLi4uREVGQVVMVF9WRUNUT1JfQ09ORklHLmNodW5raW5nLCAuLi5jb25maWcgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDthY3siqTtirjrpbwg7LKt7YGs66GcIOu2hO2VoFxuICAgKi9cbiAgY2h1bmsodGV4dDogc3RyaW5nKTogQ2h1bmtbXSB7XG4gICAgaWYgKHRleHQubGVuZ3RoIDwgdGhpcy5jb25maWcuc2tpcFRocmVzaG9sZCkge1xuICAgICAgcmV0dXJuIFtcbiAgICAgICAge1xuICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgIHRleHQ6IHRleHQudHJpbSgpLFxuICAgICAgICAgIHN0YXJ0T2Zmc2V0OiAwLFxuICAgICAgICAgIGVuZE9mZnNldDogdGV4dC5sZW5ndGgsXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgIH1cblxuICAgIGNvbnN0IGNodW5rczogQ2h1bmtbXSA9IFtdO1xuICAgIGxldCBjdXJyZW50UG9zaXRpb24gPSAwO1xuXG4gICAgd2hpbGUgKGN1cnJlbnRQb3NpdGlvbiA8IHRleHQubGVuZ3RoKSB7XG4gICAgICBjb25zdCByZW1haW5pbmdUZXh0ID0gdGV4dC5zbGljZShjdXJyZW50UG9zaXRpb24pO1xuICAgICAgY29uc3QgeyBjaHVuaywgbGVuZ3RoIH0gPSB0aGlzLmV4dHJhY3RDaHVuayhyZW1haW5pbmdUZXh0KTtcblxuICAgICAgaWYgKGNodW5rLnRyaW0oKS5sZW5ndGggPj0gdGhpcy5jb25maWcubWluQ2h1bmtTaXplKSB7XG4gICAgICAgIGNodW5rcy5wdXNoKHtcbiAgICAgICAgICBpbmRleDogY2h1bmtzLmxlbmd0aCxcbiAgICAgICAgICB0ZXh0OiBjaHVuay50cmltKCksXG4gICAgICAgICAgc3RhcnRPZmZzZXQ6IGN1cnJlbnRQb3NpdGlvbixcbiAgICAgICAgICBlbmRPZmZzZXQ6IGN1cnJlbnRQb3NpdGlvbiArIGxlbmd0aCxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFkdmFuY2UgPSBNYXRoLm1heChsZW5ndGggLSB0aGlzLmNvbmZpZy5jaHVua092ZXJsYXAsIHRoaXMuY29uZmlnLm1pbkNodW5rU2l6ZSk7XG4gICAgICBjdXJyZW50UG9zaXRpb24gKz0gYWR2YW5jZTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2h1bmtzO1xuICB9XG5cbiAgLyoqXG4gICAqIOyyre2CueydtCDtlYTsmpTtlZzsp4Ag7ZmV7J24XG4gICAqL1xuICBuZWVkc0NodW5raW5nKHRleHQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0ZXh0Lmxlbmd0aCA+IHRoaXMuY29uZmlnLmNodW5rU2l6ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiDsmIjsg4Eg7LKt7YGsIOyImCDqs4TsgrBcbiAgICovXG4gIGVzdGltYXRlQ2h1bmtDb3VudCh0ZXh0OiBzdHJpbmcpOiBudW1iZXIge1xuICAgIGlmICh0ZXh0Lmxlbmd0aCA8PSB0aGlzLmNvbmZpZy5jaHVua1NpemUpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgICBjb25zdCBlZmZlY3RpdmVDaHVua1NpemUgPSB0aGlzLmNvbmZpZy5jaHVua1NpemUgLSB0aGlzLmNvbmZpZy5jaHVua092ZXJsYXA7XG4gICAgcmV0dXJuIE1hdGguY2VpbCh0ZXh0Lmxlbmd0aCAvIGVmZmVjdGl2ZUNodW5rU2l6ZSk7XG4gIH1cblxuICBwcml2YXRlIGV4dHJhY3RDaHVuayh0ZXh0OiBzdHJpbmcpOiB7IGNodW5rOiBzdHJpbmc7IGxlbmd0aDogbnVtYmVyIH0ge1xuICAgIGlmICh0ZXh0Lmxlbmd0aCA8PSB0aGlzLmNvbmZpZy5jaHVua1NpemUpIHtcbiAgICAgIHJldHVybiB7IGNodW5rOiB0ZXh0LCBsZW5ndGg6IHRleHQubGVuZ3RoIH07XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBzZXBhcmF0b3Igb2YgdGhpcy5jb25maWcuc2VwYXJhdG9ycykge1xuICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5zcGxpdEJ5U2VwYXJhdG9yKHRleHQsIHNlcGFyYXRvcik7XG4gICAgICBpZiAocmVzdWx0KSByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBjaHVuazogdGV4dC5zbGljZSgwLCB0aGlzLmNvbmZpZy5jaHVua1NpemUpLFxuICAgICAgbGVuZ3RoOiB0aGlzLmNvbmZpZy5jaHVua1NpemUsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgc3BsaXRCeVNlcGFyYXRvcihcbiAgICB0ZXh0OiBzdHJpbmcsXG4gICAgc2VwYXJhdG9yOiBzdHJpbmcsXG4gICk6IHsgY2h1bms6IHN0cmluZzsgbGVuZ3RoOiBudW1iZXIgfSB8IG51bGwge1xuICAgIGNvbnN0IHNlYXJjaFJhbmdlID0gdGV4dC5zbGljZSgwLCB0aGlzLmNvbmZpZy5jaHVua1NpemUgKyAxMDApO1xuXG4gICAgbGV0IGxhc3RJbmRleCA9IC0xO1xuICAgIGxldCBpbmRleCA9IDA7XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgaW5kZXggPSBzZWFyY2hSYW5nZS5pbmRleE9mKHNlcGFyYXRvciwgaW5kZXgpO1xuICAgICAgaWYgKGluZGV4ID09PSAtMSkgYnJlYWs7XG4gICAgICBpZiAoaW5kZXggPD0gdGhpcy5jb25maWcuY2h1bmtTaXplKSB7XG4gICAgICAgIGxhc3RJbmRleCA9IGluZGV4ICsgc2VwYXJhdG9yLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIGluZGV4Kys7XG4gICAgfVxuXG4gICAgaWYgKGxhc3RJbmRleCA+IHRoaXMuY29uZmlnLm1pbkNodW5rU2l6ZSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY2h1bms6IHRleHQuc2xpY2UoMCwgbGFzdEluZGV4KSxcbiAgICAgICAgbGVuZ3RoOiBsYXN0SW5kZXgsXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG59XG4iXSwibmFtZXMiOlsiREVGQVVMVF9WRUNUT1JfQ09ORklHIiwiQ2h1bmtpbmciLCJjb25maWciLCJjaHVua2luZyIsImNodW5rIiwidGV4dCIsImxlbmd0aCIsInNraXBUaHJlc2hvbGQiLCJpbmRleCIsInRyaW0iLCJzdGFydE9mZnNldCIsImVuZE9mZnNldCIsImNodW5rcyIsImN1cnJlbnRQb3NpdGlvbiIsInJlbWFpbmluZ1RleHQiLCJzbGljZSIsImV4dHJhY3RDaHVuayIsIm1pbkNodW5rU2l6ZSIsInB1c2giLCJhZHZhbmNlIiwiTWF0aCIsIm1heCIsImNodW5rT3ZlcmxhcCIsIm5lZWRzQ2h1bmtpbmciLCJjaHVua1NpemUiLCJlc3RpbWF0ZUNodW5rQ291bnQiLCJlZmZlY3RpdmVDaHVua1NpemUiLCJjZWlsIiwic2VwYXJhdG9yIiwic2VwYXJhdG9ycyIsInJlc3VsdCIsInNwbGl0QnlTZXBhcmF0b3IiLCJzZWFyY2hSYW5nZSIsImxhc3RJbmRleCIsImluZGV4T2YiXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLHFCQUFxQixRQUFRLGNBQVc7QUFHakQ7Ozs7Q0FJQyxHQUNE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
@@ -0,0 +1,12 @@
1
+ import type { VectorConfig } from "./types";
2
+ /**
3
+ * 벡터 검색 기본 설정
4
+ * 사용자는 이 설정을 override하여 커스터마이즈할 수 있음
5
+ */
6
+ export declare const DEFAULT_VECTOR_CONFIG: VectorConfig;
7
+ /**
8
+ * 설정 생성 헬퍼 함수
9
+ * 부분 설정만 제공하면 나머지는 기본값 사용
10
+ */
11
+ export declare function createVectorConfig(overrides?: Partial<VectorConfig>): VectorConfig;
12
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/vector/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,YA6CnC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,GAAE,OAAO,CAAC,YAAY,CAAM,GACpC,YAAY,CAQd"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * 벡터 검색 기본 설정
3
+ * 사용자는 이 설정을 override하여 커스터마이즈할 수 있음
4
+ */ export const DEFAULT_VECTOR_CONFIG = {
5
+ // Voyage AI 설정
6
+ // apiKey는 Sonamu.secrets에서 로드되므로 여기서는 빈 문자열
7
+ voyage: {
8
+ apiKey: "",
9
+ baseUrl: "https://api.voyageai.com/v1/embeddings",
10
+ model: "voyage-3",
11
+ dimensions: 1024,
12
+ maxTokens: 32000,
13
+ batchSize: 100
14
+ },
15
+ // OpenAI 설정
16
+ // apiKey는 Sonamu.secrets에서 로드되므로 여기서는 빈 문자열
17
+ openai: {
18
+ apiKey: "",
19
+ baseUrl: "https://api.openai.com/v1/embeddings",
20
+ model: "text-embedding-3-small",
21
+ dimensions: 1536,
22
+ maxTokens: 8191,
23
+ batchSize: 100
24
+ },
25
+ // 청킹 설정 (필요시 사용)
26
+ chunking: {
27
+ chunkSize: 500,
28
+ chunkOverlap: 50,
29
+ minChunkSize: 50,
30
+ skipThreshold: 200,
31
+ separators: [
32
+ "\n\n",
33
+ "\n",
34
+ "。",
35
+ ". ",
36
+ "! ",
37
+ "? ",
38
+ ", ",
39
+ " "
40
+ ]
41
+ },
42
+ // 검색 설정
43
+ search: {
44
+ defaultLimit: 10,
45
+ similarityThreshold: 0.5,
46
+ vectorWeight: 0.7,
47
+ ftsWeight: 0.3
48
+ },
49
+ // pgvector 설정
50
+ pgvector: {
51
+ iterativeScan: true,
52
+ efSearch: 100
53
+ }
54
+ };
55
+ /**
56
+ * 설정 생성 헬퍼 함수
57
+ * 부분 설정만 제공하면 나머지는 기본값 사용
58
+ */ export function createVectorConfig(overrides = {}) {
59
+ return {
60
+ voyage: {
61
+ ...DEFAULT_VECTOR_CONFIG.voyage,
62
+ ...overrides.voyage
63
+ },
64
+ openai: {
65
+ ...DEFAULT_VECTOR_CONFIG.openai,
66
+ ...overrides.openai
67
+ },
68
+ chunking: {
69
+ ...DEFAULT_VECTOR_CONFIG.chunking,
70
+ ...overrides.chunking
71
+ },
72
+ search: {
73
+ ...DEFAULT_VECTOR_CONFIG.search,
74
+ ...overrides.search
75
+ },
76
+ pgvector: {
77
+ ...DEFAULT_VECTOR_CONFIG.pgvector,
78
+ ...overrides.pgvector
79
+ }
80
+ };
81
+ }
82
+
83
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92ZWN0b3IvY29uZmlnLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgVmVjdG9yQ29uZmlnIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiDrsqHthLAg6rKA7IOJIOq4sOuzuCDshKTsoJVcbiAqIOyCrOyaqeyekOuKlCDsnbQg7ISk7KCV7J2EIG92ZXJyaWRl7ZWY7JesIOy7pOyKpO2EsOuniOydtOymiO2VoCDsiJgg7J6I7J2MXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX1ZFQ1RPUl9DT05GSUc6IFZlY3RvckNvbmZpZyA9IHtcbiAgLy8gVm95YWdlIEFJIOyEpOyglVxuICAvLyBhcGlLZXnripQgU29uYW11LnNlY3JldHPsl5DshJwg66Gc65Oc65CY66+A66GcIOyXrOq4sOyEnOuKlCDruYgg66y47J6Q7Je0XG4gIHZveWFnZToge1xuICAgIGFwaUtleTogXCJcIixcbiAgICBiYXNlVXJsOiBcImh0dHBzOi8vYXBpLnZveWFnZWFpLmNvbS92MS9lbWJlZGRpbmdzXCIsXG4gICAgbW9kZWw6IFwidm95YWdlLTNcIixcbiAgICBkaW1lbnNpb25zOiAxMDI0LFxuICAgIG1heFRva2VuczogMzIwMDAsXG4gICAgYmF0Y2hTaXplOiAxMDAsXG4gIH0sXG5cbiAgLy8gT3BlbkFJIOyEpOyglVxuICAvLyBhcGlLZXnripQgU29uYW11LnNlY3JldHPsl5DshJwg66Gc65Oc65CY66+A66GcIOyXrOq4sOyEnOuKlCDruYgg66y47J6Q7Je0XG4gIG9wZW5haToge1xuICAgIGFwaUtleTogXCJcIixcbiAgICBiYXNlVXJsOiBcImh0dHBzOi8vYXBpLm9wZW5haS5jb20vdjEvZW1iZWRkaW5nc1wiLFxuICAgIG1vZGVsOiBcInRleHQtZW1iZWRkaW5nLTMtc21hbGxcIixcbiAgICBkaW1lbnNpb25zOiAxNTM2LFxuICAgIG1heFRva2VuczogODE5MSxcbiAgICBiYXRjaFNpemU6IDEwMCxcbiAgfSxcblxuICAvLyDssq3tgrkg7ISk7KCVICjtlYTsmpTsi5wg7IKs7JqpKVxuICBjaHVua2luZzoge1xuICAgIGNodW5rU2l6ZTogNTAwLFxuICAgIGNodW5rT3ZlcmxhcDogNTAsXG4gICAgbWluQ2h1bmtTaXplOiA1MCxcbiAgICBza2lwVGhyZXNob2xkOiAyMDAsXG4gICAgc2VwYXJhdG9yczogW1wiXFxuXFxuXCIsIFwiXFxuXCIsIFwi44CCXCIsIFwiLiBcIiwgXCIhIFwiLCBcIj8gXCIsIFwiLCBcIiwgXCIgXCJdLFxuICB9LFxuXG4gIC8vIOqygOyDiSDshKTsoJVcbiAgc2VhcmNoOiB7XG4gICAgZGVmYXVsdExpbWl0OiAxMCxcbiAgICBzaW1pbGFyaXR5VGhyZXNob2xkOiAwLjUsXG4gICAgdmVjdG9yV2VpZ2h0OiAwLjcsXG4gICAgZnRzV2VpZ2h0OiAwLjMsXG4gIH0sXG5cbiAgLy8gcGd2ZWN0b3Ig7ISk7KCVXG4gIHBndmVjdG9yOiB7XG4gICAgaXRlcmF0aXZlU2NhbjogdHJ1ZSxcbiAgICBlZlNlYXJjaDogMTAwLFxuICB9LFxufTtcblxuLyoqXG4gKiDshKTsoJUg7IOd7ISxIO2XrO2NvCDtlajsiJhcbiAqIOu2gOu2hCDshKTsoJXrp4wg7KCc6rO17ZWY66m0IOuCmOuouOyngOuKlCDquLDrs7jqsJIg7IKs7JqpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVWZWN0b3JDb25maWcoXG4gIG92ZXJyaWRlczogUGFydGlhbDxWZWN0b3JDb25maWc+ID0ge31cbik6IFZlY3RvckNvbmZpZyB7XG4gIHJldHVybiB7XG4gICAgdm95YWdlOiB7IC4uLkRFRkFVTFRfVkVDVE9SX0NPTkZJRy52b3lhZ2UsIC4uLm92ZXJyaWRlcy52b3lhZ2UgfSxcbiAgICBvcGVuYWk6IHsgLi4uREVGQVVMVF9WRUNUT1JfQ09ORklHLm9wZW5haSwgLi4ub3ZlcnJpZGVzLm9wZW5haSB9LFxuICAgIGNodW5raW5nOiB7IC4uLkRFRkFVTFRfVkVDVE9SX0NPTkZJRy5jaHVua2luZywgLi4ub3ZlcnJpZGVzLmNodW5raW5nIH0sXG4gICAgc2VhcmNoOiB7IC4uLkRFRkFVTFRfVkVDVE9SX0NPTkZJRy5zZWFyY2gsIC4uLm92ZXJyaWRlcy5zZWFyY2ggfSxcbiAgICBwZ3ZlY3RvcjogeyAuLi5ERUZBVUxUX1ZFQ1RPUl9DT05GSUcucGd2ZWN0b3IsIC4uLm92ZXJyaWRlcy5wZ3ZlY3RvciB9LFxuICB9O1xufVxuIl0sIm5hbWVzIjpbIkRFRkFVTFRfVkVDVE9SX0NPTkZJRyIsInZveWFnZSIsImFwaUtleSIsImJhc2VVcmwiLCJtb2RlbCIsImRpbWVuc2lvbnMiLCJtYXhUb2tlbnMiLCJiYXRjaFNpemUiLCJvcGVuYWkiLCJjaHVua2luZyIsImNodW5rU2l6ZSIsImNodW5rT3ZlcmxhcCIsIm1pbkNodW5rU2l6ZSIsInNraXBUaHJlc2hvbGQiLCJzZXBhcmF0b3JzIiwic2VhcmNoIiwiZGVmYXVsdExpbWl0Iiwic2ltaWxhcml0eVRocmVzaG9sZCIsInZlY3RvcldlaWdodCIsImZ0c1dlaWdodCIsInBndmVjdG9yIiwiaXRlcmF0aXZlU2NhbiIsImVmU2VhcmNoIiwiY3JlYXRlVmVjdG9yQ29uZmlnIiwib3ZlcnJpZGVzIl0sIm1hcHBpbmdzIjoiQUFFQTs7O0NBR0MsR0FDRCxPQUFPLE1BQU1BLHdCQUFzQztJQUNqRCxlQUFlO0lBQ2YsNENBQTRDO0lBQzVDQyxRQUFRO1FBQ05DLFFBQVE7UUFDUkMsU0FBUztRQUNUQyxPQUFPO1FBQ1BDLFlBQVk7UUFDWkMsV0FBVztRQUNYQyxXQUFXO0lBQ2I7SUFFQSxZQUFZO0lBQ1osNENBQTRDO0lBQzVDQyxRQUFRO1FBQ05OLFFBQVE7UUFDUkMsU0FBUztRQUNUQyxPQUFPO1FBQ1BDLFlBQVk7UUFDWkMsV0FBVztRQUNYQyxXQUFXO0lBQ2I7SUFFQSxpQkFBaUI7SUFDakJFLFVBQVU7UUFDUkMsV0FBVztRQUNYQyxjQUFjO1FBQ2RDLGNBQWM7UUFDZEMsZUFBZTtRQUNmQyxZQUFZO1lBQUM7WUFBUTtZQUFNO1lBQUs7WUFBTTtZQUFNO1lBQU07WUFBTTtTQUFJO0lBQzlEO0lBRUEsUUFBUTtJQUNSQyxRQUFRO1FBQ05DLGNBQWM7UUFDZEMscUJBQXFCO1FBQ3JCQyxjQUFjO1FBQ2RDLFdBQVc7SUFDYjtJQUVBLGNBQWM7SUFDZEMsVUFBVTtRQUNSQyxlQUFlO1FBQ2ZDLFVBQVU7SUFDWjtBQUNGLEVBQUU7QUFFRjs7O0NBR0MsR0FDRCxPQUFPLFNBQVNDLG1CQUNkQyxZQUFtQyxDQUFDLENBQUM7SUFFckMsT0FBTztRQUNMdkIsUUFBUTtZQUFFLEdBQUdELHNCQUFzQkMsTUFBTTtZQUFFLEdBQUd1QixVQUFVdkIsTUFBTTtRQUFDO1FBQy9ETyxRQUFRO1lBQUUsR0FBR1Isc0JBQXNCUSxNQUFNO1lBQUUsR0FBR2dCLFVBQVVoQixNQUFNO1FBQUM7UUFDL0RDLFVBQVU7WUFBRSxHQUFHVCxzQkFBc0JTLFFBQVE7WUFBRSxHQUFHZSxVQUFVZixRQUFRO1FBQUM7UUFDckVNLFFBQVE7WUFBRSxHQUFHZixzQkFBc0JlLE1BQU07WUFBRSxHQUFHUyxVQUFVVCxNQUFNO1FBQUM7UUFDL0RLLFVBQVU7WUFBRSxHQUFHcEIsc0JBQXNCb0IsUUFBUTtZQUFFLEdBQUdJLFVBQVVKLFFBQVE7UUFBQztJQUN2RTtBQUNGIn0=
@@ -0,0 +1,42 @@
1
+ import type { EmbeddingProvider, EmbeddingResult, ProgressCallback, VectorConfig, VectorInputType } from "./types";
2
+ /**
3
+ * 임베딩 클라이언트
4
+ * Voyage AI와 OpenAI 임베딩을 통합 지원
5
+ */
6
+ export declare class Embedding {
7
+ private config;
8
+ constructor(config?: Partial<VectorConfig>);
9
+ /**
10
+ * 텍스트 임베딩 생성
11
+ * @param texts - 임베딩할 텍스트 배열
12
+ * @param provider - 'voyage' | 'openai'
13
+ * @param inputType - 'document' | 'query' (Voyage AI만 해당)
14
+ */
15
+ embed(texts: string[], provider: EmbeddingProvider, inputType?: VectorInputType): Promise<EmbeddingResult[]>;
16
+ /**
17
+ * 단일 텍스트 임베딩 (편의 메서드)
18
+ */
19
+ embedOne(text: string, provider: EmbeddingProvider, inputType?: VectorInputType): Promise<EmbeddingResult>;
20
+ /**
21
+ * Voyage AI 임베딩
22
+ */
23
+ private embedVoyage;
24
+ /**
25
+ * OpenAI 임베딩
26
+ */
27
+ private embedOpenAI;
28
+ /**
29
+ * 배치 임베딩 (대량 처리)
30
+ */
31
+ embedBatch(texts: string[], provider: EmbeddingProvider, inputType?: VectorInputType, onProgress?: ProgressCallback): Promise<EmbeddingResult[]>;
32
+ /**
33
+ * 벡터를 PostgreSQL vector 타입 문자열로 변환
34
+ */
35
+ static toVectorString(embedding: number[]): string;
36
+ /**
37
+ * 임베딩 provider의 차원 수 반환
38
+ */
39
+ getDimensions(provider: EmbeddingProvider): number;
40
+ private delay;
41
+ }
42
+ //# sourceMappingURL=embedding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding.d.ts","sourceRoot":"","sources":["../../src/vector/embedding.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,eAAe,EAChB,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAe;gBAEjB,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM;IAU9C;;;;;OAKG;IACG,KAAK,CACT,KAAK,EAAE,MAAM,EAAE,EACf,QAAQ,EAAE,iBAAiB,EAC3B,SAAS,GAAE,eAA4B,GACtC,OAAO,CAAC,eAAe,EAAE,CAAC;IAQ7B;;OAEG;IACG,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,iBAAiB,EAC3B,SAAS,GAAE,eAA4B,GACtC,OAAO,CAAC,eAAe,CAAC;IAK3B;;OAEG;YACW,WAAW;IAyCzB;;OAEG;YACW,WAAW;IAqCzB;;OAEG;IACG,UAAU,CACd,KAAK,EAAE,MAAM,EAAE,EACf,QAAQ,EAAE,iBAAiB,EAC3B,SAAS,GAAE,eAA4B,EACvC,UAAU,CAAC,EAAE,gBAAgB,GAC5B,OAAO,CAAC,eAAe,EAAE,CAAC;IAwB7B;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM;IAIlD;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM;IAMlD,OAAO,CAAC,KAAK;CAGd"}
@@ -0,0 +1,147 @@
1
+ import { Sonamu } from "../api/sonamu.js";
2
+ import { DEFAULT_VECTOR_CONFIG } from "./config.js";
3
+ /**
4
+ * 임베딩 클라이언트
5
+ * Voyage AI와 OpenAI 임베딩을 통합 지원
6
+ */ export class Embedding {
7
+ config;
8
+ constructor(config = {}){
9
+ this.config = {
10
+ voyage: {
11
+ ...DEFAULT_VECTOR_CONFIG.voyage,
12
+ ...config.voyage
13
+ },
14
+ openai: {
15
+ ...DEFAULT_VECTOR_CONFIG.openai,
16
+ ...config.openai
17
+ },
18
+ chunking: {
19
+ ...DEFAULT_VECTOR_CONFIG.chunking,
20
+ ...config.chunking
21
+ },
22
+ search: {
23
+ ...DEFAULT_VECTOR_CONFIG.search,
24
+ ...config.search
25
+ },
26
+ pgvector: {
27
+ ...DEFAULT_VECTOR_CONFIG.pgvector,
28
+ ...config.pgvector
29
+ }
30
+ };
31
+ }
32
+ /**
33
+ * 텍스트 임베딩 생성
34
+ * @param texts - 임베딩할 텍스트 배열
35
+ * @param provider - 'voyage' | 'openai'
36
+ * @param inputType - 'document' | 'query' (Voyage AI만 해당)
37
+ */ async embed(texts, provider, inputType = "document") {
38
+ if (provider === "voyage") {
39
+ return this.embedVoyage(texts, inputType);
40
+ } else {
41
+ return this.embedOpenAI(texts);
42
+ }
43
+ }
44
+ /**
45
+ * 단일 텍스트 임베딩 (편의 메서드)
46
+ */ async embedOne(text, provider, inputType = "document") {
47
+ const results = await this.embed([
48
+ text
49
+ ], provider, inputType);
50
+ return results[0];
51
+ }
52
+ /**
53
+ * Voyage AI 임베딩
54
+ */ async embedVoyage(texts, inputType) {
55
+ const voyageConfig = this.config.voyage;
56
+ // config에서 설정된 apiKey 우선, 없으면 Sonamu.secrets에서 로드
57
+ const apiKey = voyageConfig.apiKey || Sonamu.secrets?.voyage_api_key;
58
+ if (!apiKey) {
59
+ throw new Error("VOYAGE_API_KEY가 설정되지 않았습니다. 환경변수를 확인하세요.");
60
+ }
61
+ const response = await fetch(voyageConfig.baseUrl, {
62
+ method: "POST",
63
+ headers: {
64
+ "Content-Type": "application/json",
65
+ Authorization: `Bearer ${apiKey}`
66
+ },
67
+ body: JSON.stringify({
68
+ input: texts,
69
+ model: voyageConfig.model,
70
+ input_type: inputType
71
+ })
72
+ });
73
+ if (!response.ok) {
74
+ const error = await response.text();
75
+ throw new Error(`Voyage API error: ${response.status} - ${error}`);
76
+ }
77
+ const data = await response.json();
78
+ return data.data.map((item)=>({
79
+ embedding: item.embedding,
80
+ model: voyageConfig.model,
81
+ tokenCount: data.usage?.total_tokens || 0
82
+ }));
83
+ }
84
+ /**
85
+ * OpenAI 임베딩
86
+ */ async embedOpenAI(texts) {
87
+ const openaiConfig = this.config.openai;
88
+ // config에서 설정된 apiKey 우선, 없으면 Sonamu.secrets에서 로드
89
+ const apiKey = openaiConfig.apiKey || Sonamu.secrets?.openai_api_key;
90
+ if (!apiKey) {
91
+ throw new Error("OPENAI_API_KEY가 설정되지 않았습니다. 환경변수를 확인하세요.");
92
+ }
93
+ const response = await fetch(openaiConfig.baseUrl, {
94
+ method: "POST",
95
+ headers: {
96
+ "Content-Type": "application/json",
97
+ Authorization: `Bearer ${apiKey}`
98
+ },
99
+ body: JSON.stringify({
100
+ input: texts,
101
+ model: openaiConfig.model
102
+ })
103
+ });
104
+ if (!response.ok) {
105
+ const error = await response.text();
106
+ throw new Error(`OpenAI API error: ${response.status} - ${error}`);
107
+ }
108
+ const data = await response.json();
109
+ return data.data.map((item)=>({
110
+ embedding: item.embedding,
111
+ model: openaiConfig.model,
112
+ tokenCount: data.usage?.total_tokens || 0
113
+ }));
114
+ }
115
+ /**
116
+ * 배치 임베딩 (대량 처리)
117
+ */ async embedBatch(texts, provider, inputType = "document", onProgress) {
118
+ const batchSize = provider === "voyage" ? this.config.voyage.batchSize : this.config.openai.batchSize;
119
+ const results = [];
120
+ for(let i = 0; i < texts.length; i += batchSize){
121
+ const batch = texts.slice(i, i + batchSize);
122
+ const batchResults = await this.embed(batch, provider, inputType);
123
+ results.push(...batchResults);
124
+ onProgress?.(Math.min(i + batchSize, texts.length), texts.length);
125
+ // Rate limiting (100ms between batches)
126
+ if (i + batchSize < texts.length) {
127
+ await this.delay(100);
128
+ }
129
+ }
130
+ return results;
131
+ }
132
+ /**
133
+ * 벡터를 PostgreSQL vector 타입 문자열로 변환
134
+ */ static toVectorString(embedding) {
135
+ return `[${embedding.join(",")}]`;
136
+ }
137
+ /**
138
+ * 임베딩 provider의 차원 수 반환
139
+ */ getDimensions(provider) {
140
+ return provider === "voyage" ? this.config.voyage.dimensions : this.config.openai.dimensions;
141
+ }
142
+ delay(ms) {
143
+ return new Promise((resolve)=>setTimeout(resolve, ms));
144
+ }
145
+ }
146
+
147
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92ZWN0b3IvZW1iZWRkaW5nLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFNvbmFtdSB9IGZyb20gXCIuLi9hcGkvc29uYW11XCI7XG5pbXBvcnQgeyBERUZBVUxUX1ZFQ1RPUl9DT05GSUcgfSBmcm9tIFwiLi9jb25maWdcIjtcbmltcG9ydCB0eXBlIHtcbiAgRW1iZWRkaW5nUHJvdmlkZXIsXG4gIEVtYmVkZGluZ1Jlc3VsdCxcbiAgUHJvZ3Jlc3NDYWxsYmFjayxcbiAgVmVjdG9yQ29uZmlnLFxuICBWZWN0b3JJbnB1dFR5cGUsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICog7J6E67Kg65SpIO2BtOudvOydtOyWuO2KuFxuICogVm95YWdlIEFJ7JmAIE9wZW5BSSDsnoTrsqDrlKnsnYQg7Ya17ZWpIOyngOybkFxuICovXG5leHBvcnQgY2xhc3MgRW1iZWRkaW5nIHtcbiAgcHJpdmF0ZSBjb25maWc6IFZlY3RvckNvbmZpZztcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IFBhcnRpYWw8VmVjdG9yQ29uZmlnPiA9IHt9KSB7XG4gICAgdGhpcy5jb25maWcgPSB7XG4gICAgICB2b3lhZ2U6IHsgLi4uREVGQVVMVF9WRUNUT1JfQ09ORklHLnZveWFnZSwgLi4uY29uZmlnLnZveWFnZSB9LFxuICAgICAgb3BlbmFpOiB7IC4uLkRFRkFVTFRfVkVDVE9SX0NPTkZJRy5vcGVuYWksIC4uLmNvbmZpZy5vcGVuYWkgfSxcbiAgICAgIGNodW5raW5nOiB7IC4uLkRFRkFVTFRfVkVDVE9SX0NPTkZJRy5jaHVua2luZywgLi4uY29uZmlnLmNodW5raW5nIH0sXG4gICAgICBzZWFyY2g6IHsgLi4uREVGQVVMVF9WRUNUT1JfQ09ORklHLnNlYXJjaCwgLi4uY29uZmlnLnNlYXJjaCB9LFxuICAgICAgcGd2ZWN0b3I6IHsgLi4uREVGQVVMVF9WRUNUT1JfQ09ORklHLnBndmVjdG9yLCAuLi5jb25maWcucGd2ZWN0b3IgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIO2FjeyKpO2KuCDsnoTrsqDrlKkg7IOd7ISxXG4gICAqIEBwYXJhbSB0ZXh0cyAtIOyehOuyoOuUqe2VoCDthY3siqTtirgg67Cw7Je0XG4gICAqIEBwYXJhbSBwcm92aWRlciAtICd2b3lhZ2UnIHwgJ29wZW5haSdcbiAgICogQHBhcmFtIGlucHV0VHlwZSAtICdkb2N1bWVudCcgfCAncXVlcnknIChWb3lhZ2UgQUnrp4wg7ZW064u5KVxuICAgKi9cbiAgYXN5bmMgZW1iZWQoXG4gICAgdGV4dHM6IHN0cmluZ1tdLFxuICAgIHByb3ZpZGVyOiBFbWJlZGRpbmdQcm92aWRlcixcbiAgICBpbnB1dFR5cGU6IFZlY3RvcklucHV0VHlwZSA9IFwiZG9jdW1lbnRcIlxuICApOiBQcm9taXNlPEVtYmVkZGluZ1Jlc3VsdFtdPiB7XG4gICAgaWYgKHByb3ZpZGVyID09PSBcInZveWFnZVwiKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbWJlZFZveWFnZSh0ZXh0cywgaW5wdXRUeXBlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuZW1iZWRPcGVuQUkodGV4dHMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDri6jsnbwg7YWN7Iqk7Yq4IOyehOuyoOuUqSAo7Y647J2YIOuplOyEnOuTnClcbiAgICovXG4gIGFzeW5jIGVtYmVkT25lKFxuICAgIHRleHQ6IHN0cmluZyxcbiAgICBwcm92aWRlcjogRW1iZWRkaW5nUHJvdmlkZXIsXG4gICAgaW5wdXRUeXBlOiBWZWN0b3JJbnB1dFR5cGUgPSBcImRvY3VtZW50XCJcbiAgKTogUHJvbWlzZTxFbWJlZGRpbmdSZXN1bHQ+IHtcbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5lbWJlZChbdGV4dF0sIHByb3ZpZGVyLCBpbnB1dFR5cGUpO1xuICAgIHJldHVybiByZXN1bHRzWzBdO1xuICB9XG5cbiAgLyoqXG4gICAqIFZveWFnZSBBSSDsnoTrsqDrlKlcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW1iZWRWb3lhZ2UoXG4gICAgdGV4dHM6IHN0cmluZ1tdLFxuICAgIGlucHV0VHlwZTogVmVjdG9ySW5wdXRUeXBlXG4gICk6IFByb21pc2U8RW1iZWRkaW5nUmVzdWx0W10+IHtcbiAgICBjb25zdCB2b3lhZ2VDb25maWcgPSB0aGlzLmNvbmZpZy52b3lhZ2U7XG5cbiAgICAvLyBjb25maWfsl5DshJwg7ISk7KCV65CcIGFwaUtleSDsmrDshKAsIOyXhuycvOuptCBTb25hbXUuc2VjcmV0c+yXkOyEnCDroZzrk5xcbiAgICBjb25zdCBhcGlLZXkgPSB2b3lhZ2VDb25maWcuYXBpS2V5IHx8IFNvbmFtdS5zZWNyZXRzPy52b3lhZ2VfYXBpX2tleTtcbiAgICBpZiAoIWFwaUtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcIlZPWUFHRV9BUElfS0VZ6rCAIOyEpOygleuQmOyngCDslYrslZjsirXri4jri6QuIO2ZmOqyveuzgOyImOulvCDtmZXsnbjtlZjshLjsmpQuXCJcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh2b3lhZ2VDb25maWcuYmFzZVVybCwge1xuICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gICAgICAgIEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHthcGlLZXl9YCxcbiAgICAgIH0sXG4gICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIGlucHV0OiB0ZXh0cyxcbiAgICAgICAgbW9kZWw6IHZveWFnZUNvbmZpZy5tb2RlbCxcbiAgICAgICAgaW5wdXRfdHlwZTogaW5wdXRUeXBlLFxuICAgICAgfSksXG4gICAgfSk7XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICBjb25zdCBlcnJvciA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVm95YWdlIEFQSSBlcnJvcjogJHtyZXNwb25zZS5zdGF0dXN9IC0gJHtlcnJvcn1gKTtcbiAgICB9XG5cbiAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuXG4gICAgcmV0dXJuIGRhdGEuZGF0YS5tYXAoKGl0ZW06IHsgZW1iZWRkaW5nOiBudW1iZXJbXSB9KSA9PiAoe1xuICAgICAgZW1iZWRkaW5nOiBpdGVtLmVtYmVkZGluZyxcbiAgICAgIG1vZGVsOiB2b3lhZ2VDb25maWcubW9kZWwsXG4gICAgICB0b2tlbkNvdW50OiBkYXRhLnVzYWdlPy50b3RhbF90b2tlbnMgfHwgMCxcbiAgICB9KSk7XG4gIH1cblxuICAvKipcbiAgICogT3BlbkFJIOyehOuyoOuUqVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBlbWJlZE9wZW5BSSh0ZXh0czogc3RyaW5nW10pOiBQcm9taXNlPEVtYmVkZGluZ1Jlc3VsdFtdPiB7XG4gICAgY29uc3Qgb3BlbmFpQ29uZmlnID0gdGhpcy5jb25maWcub3BlbmFpO1xuXG4gICAgLy8gY29uZmln7JeQ7IScIOyEpOygleuQnCBhcGlLZXkg7Jqw7ISgLCDsl4bsnLzrqbQgU29uYW11LnNlY3JldHPsl5DshJwg66Gc65OcXG4gICAgY29uc3QgYXBpS2V5ID0gb3BlbmFpQ29uZmlnLmFwaUtleSB8fCBTb25hbXUuc2VjcmV0cz8ub3BlbmFpX2FwaV9rZXk7XG4gICAgaWYgKCFhcGlLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJPUEVOQUlfQVBJX0tFWeqwgCDshKTsoJXrkJjsp4Ag7JWK7JWY7Iq164uI64ukLiDtmZjqsr3rs4DsiJjrpbwg7ZmV7J247ZWY7IS47JqULlwiXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2gob3BlbmFpQ29uZmlnLmJhc2VVcmwsIHtcbiAgICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgIFwiQ29udGVudC1UeXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgICBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7YXBpS2V5fWAsXG4gICAgICB9LFxuICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICBpbnB1dDogdGV4dHMsXG4gICAgICAgIG1vZGVsOiBvcGVuYWlDb25maWcubW9kZWwsXG4gICAgICB9KSxcbiAgICB9KTtcblxuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIGNvbnN0IGVycm9yID0gYXdhaXQgcmVzcG9uc2UudGV4dCgpO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBPcGVuQUkgQVBJIGVycm9yOiAke3Jlc3BvbnNlLnN0YXR1c30gLSAke2Vycm9yfWApO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG5cbiAgICByZXR1cm4gZGF0YS5kYXRhLm1hcCgoaXRlbTogeyBlbWJlZGRpbmc6IG51bWJlcltdIH0pID0+ICh7XG4gICAgICBlbWJlZGRpbmc6IGl0ZW0uZW1iZWRkaW5nLFxuICAgICAgbW9kZWw6IG9wZW5haUNvbmZpZy5tb2RlbCxcbiAgICAgIHRva2VuQ291bnQ6IGRhdGEudXNhZ2U/LnRvdGFsX3Rva2VucyB8fCAwLFxuICAgIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDrsLDsuZgg7J6E67Kg65SpICjrjIDrn4kg7LKY66asKVxuICAgKi9cbiAgYXN5bmMgZW1iZWRCYXRjaChcbiAgICB0ZXh0czogc3RyaW5nW10sXG4gICAgcHJvdmlkZXI6IEVtYmVkZGluZ1Byb3ZpZGVyLFxuICAgIGlucHV0VHlwZTogVmVjdG9ySW5wdXRUeXBlID0gXCJkb2N1bWVudFwiLFxuICAgIG9uUHJvZ3Jlc3M/OiBQcm9ncmVzc0NhbGxiYWNrXG4gICk6IFByb21pc2U8RW1iZWRkaW5nUmVzdWx0W10+IHtcbiAgICBjb25zdCBiYXRjaFNpemUgPVxuICAgICAgcHJvdmlkZXIgPT09IFwidm95YWdlXCJcbiAgICAgICAgPyB0aGlzLmNvbmZpZy52b3lhZ2UuYmF0Y2hTaXplXG4gICAgICAgIDogdGhpcy5jb25maWcub3BlbmFpLmJhdGNoU2l6ZTtcblxuICAgIGNvbnN0IHJlc3VsdHM6IEVtYmVkZGluZ1Jlc3VsdFtdID0gW107XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRleHRzLmxlbmd0aDsgaSArPSBiYXRjaFNpemUpIHtcbiAgICAgIGNvbnN0IGJhdGNoID0gdGV4dHMuc2xpY2UoaSwgaSArIGJhdGNoU2l6ZSk7XG4gICAgICBjb25zdCBiYXRjaFJlc3VsdHMgPSBhd2FpdCB0aGlzLmVtYmVkKGJhdGNoLCBwcm92aWRlciwgaW5wdXRUeXBlKTtcbiAgICAgIHJlc3VsdHMucHVzaCguLi5iYXRjaFJlc3VsdHMpO1xuXG4gICAgICBvblByb2dyZXNzPy4oTWF0aC5taW4oaSArIGJhdGNoU2l6ZSwgdGV4dHMubGVuZ3RoKSwgdGV4dHMubGVuZ3RoKTtcblxuICAgICAgLy8gUmF0ZSBsaW1pdGluZyAoMTAwbXMgYmV0d2VlbiBiYXRjaGVzKVxuICAgICAgaWYgKGkgKyBiYXRjaFNpemUgPCB0ZXh0cy5sZW5ndGgpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5kZWxheSgxMDApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG5cbiAgLyoqXG4gICAqIOuyoe2EsOulvCBQb3N0Z3JlU1FMIHZlY3RvciDtg4DsnoUg66y47J6Q7Je066GcIOuzgO2ZmFxuICAgKi9cbiAgc3RhdGljIHRvVmVjdG9yU3RyaW5nKGVtYmVkZGluZzogbnVtYmVyW10pOiBzdHJpbmcge1xuICAgIHJldHVybiBgWyR7ZW1iZWRkaW5nLmpvaW4oXCIsXCIpfV1gO1xuICB9XG5cbiAgLyoqXG4gICAqIOyehOuyoOuUqSBwcm92aWRlcuydmCDssKjsm5Ag7IiYIOuwmO2ZmFxuICAgKi9cbiAgZ2V0RGltZW5zaW9ucyhwcm92aWRlcjogRW1iZWRkaW5nUHJvdmlkZXIpOiBudW1iZXIge1xuICAgIHJldHVybiBwcm92aWRlciA9PT0gXCJ2b3lhZ2VcIlxuICAgICAgPyB0aGlzLmNvbmZpZy52b3lhZ2UuZGltZW5zaW9uc1xuICAgICAgOiB0aGlzLmNvbmZpZy5vcGVuYWkuZGltZW5zaW9ucztcbiAgfVxuXG4gIHByaXZhdGUgZGVsYXkobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCBtcykpO1xuICB9XG59XG4iXSwibmFtZXMiOlsiU29uYW11IiwiREVGQVVMVF9WRUNUT1JfQ09ORklHIiwiRW1iZWRkaW5nIiwiY29uZmlnIiwidm95YWdlIiwib3BlbmFpIiwiY2h1bmtpbmciLCJzZWFyY2giLCJwZ3ZlY3RvciIsImVtYmVkIiwidGV4dHMiLCJwcm92aWRlciIsImlucHV0VHlwZSIsImVtYmVkVm95YWdlIiwiZW1iZWRPcGVuQUkiLCJlbWJlZE9uZSIsInRleHQiLCJyZXN1bHRzIiwidm95YWdlQ29uZmlnIiwiYXBpS2V5Iiwic2VjcmV0cyIsInZveWFnZV9hcGlfa2V5IiwiRXJyb3IiLCJyZXNwb25zZSIsImZldGNoIiwiYmFzZVVybCIsIm1ldGhvZCIsImhlYWRlcnMiLCJBdXRob3JpemF0aW9uIiwiYm9keSIsIkpTT04iLCJzdHJpbmdpZnkiLCJpbnB1dCIsIm1vZGVsIiwiaW5wdXRfdHlwZSIsIm9rIiwiZXJyb3IiLCJzdGF0dXMiLCJkYXRhIiwianNvbiIsIm1hcCIsIml0ZW0iLCJlbWJlZGRpbmciLCJ0b2tlbkNvdW50IiwidXNhZ2UiLCJ0b3RhbF90b2tlbnMiLCJvcGVuYWlDb25maWciLCJvcGVuYWlfYXBpX2tleSIsImVtYmVkQmF0Y2giLCJvblByb2dyZXNzIiwiYmF0Y2hTaXplIiwiaSIsImxlbmd0aCIsImJhdGNoIiwic2xpY2UiLCJiYXRjaFJlc3VsdHMiLCJwdXNoIiwiTWF0aCIsIm1pbiIsImRlbGF5IiwidG9WZWN0b3JTdHJpbmciLCJqb2luIiwiZ2V0RGltZW5zaW9ucyIsImRpbWVuc2lvbnMiLCJtcyIsIlByb21pc2UiLCJyZXNvbHZlIiwic2V0VGltZW91dCJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsTUFBTSxRQUFRLG1CQUFnQjtBQUN2QyxTQUFTQyxxQkFBcUIsUUFBUSxjQUFXO0FBU2pEOzs7Q0FHQyxHQUNELE9BQU8sTUFBTUM7SUFDSEMsT0FBcUI7SUFFN0IsWUFBWUEsU0FBZ0MsQ0FBQyxDQUFDLENBQUU7UUFDOUMsSUFBSSxDQUFDQSxNQUFNLEdBQUc7WUFDWkMsUUFBUTtnQkFBRSxHQUFHSCxzQkFBc0JHLE1BQU07Z0JBQUUsR0FBR0QsT0FBT0MsTUFBTTtZQUFDO1lBQzVEQyxRQUFRO2dCQUFFLEdBQUdKLHNCQUFzQkksTUFBTTtnQkFBRSxHQUFHRixPQUFPRSxNQUFNO1lBQUM7WUFDNURDLFVBQVU7Z0JBQUUsR0FBR0wsc0JBQXNCSyxRQUFRO2dCQUFFLEdBQUdILE9BQU9HLFFBQVE7WUFBQztZQUNsRUMsUUFBUTtnQkFBRSxHQUFHTixzQkFBc0JNLE1BQU07Z0JBQUUsR0FBR0osT0FBT0ksTUFBTTtZQUFDO1lBQzVEQyxVQUFVO2dCQUFFLEdBQUdQLHNCQUFzQk8sUUFBUTtnQkFBRSxHQUFHTCxPQUFPSyxRQUFRO1lBQUM7UUFDcEU7SUFDRjtJQUVBOzs7OztHQUtDLEdBQ0QsTUFBTUMsTUFDSkMsS0FBZSxFQUNmQyxRQUEyQixFQUMzQkMsWUFBNkIsVUFBVSxFQUNYO1FBQzVCLElBQUlELGFBQWEsVUFBVTtZQUN6QixPQUFPLElBQUksQ0FBQ0UsV0FBVyxDQUFDSCxPQUFPRTtRQUNqQyxPQUFPO1lBQ0wsT0FBTyxJQUFJLENBQUNFLFdBQVcsQ0FBQ0o7UUFDMUI7SUFDRjtJQUVBOztHQUVDLEdBQ0QsTUFBTUssU0FDSkMsSUFBWSxFQUNaTCxRQUEyQixFQUMzQkMsWUFBNkIsVUFBVSxFQUNiO1FBQzFCLE1BQU1LLFVBQVUsTUFBTSxJQUFJLENBQUNSLEtBQUssQ0FBQztZQUFDTztTQUFLLEVBQUVMLFVBQVVDO1FBQ25ELE9BQU9LLE9BQU8sQ0FBQyxFQUFFO0lBQ25CO0lBRUE7O0dBRUMsR0FDRCxNQUFjSixZQUNaSCxLQUFlLEVBQ2ZFLFNBQTBCLEVBQ0U7UUFDNUIsTUFBTU0sZUFBZSxJQUFJLENBQUNmLE1BQU0sQ0FBQ0MsTUFBTTtRQUV2QyxrREFBa0Q7UUFDbEQsTUFBTWUsU0FBU0QsYUFBYUMsTUFBTSxJQUFJbkIsT0FBT29CLE9BQU8sRUFBRUM7UUFDdEQsSUFBSSxDQUFDRixRQUFRO1lBQ1gsTUFBTSxJQUFJRyxNQUNSO1FBRUo7UUFFQSxNQUFNQyxXQUFXLE1BQU1DLE1BQU1OLGFBQWFPLE9BQU8sRUFBRTtZQUNqREMsUUFBUTtZQUNSQyxTQUFTO2dCQUNQLGdCQUFnQjtnQkFDaEJDLGVBQWUsQ0FBQyxPQUFPLEVBQUVULFFBQVE7WUFDbkM7WUFDQVUsTUFBTUMsS0FBS0MsU0FBUyxDQUFDO2dCQUNuQkMsT0FBT3RCO2dCQUNQdUIsT0FBT2YsYUFBYWUsS0FBSztnQkFDekJDLFlBQVl0QjtZQUNkO1FBQ0Y7UUFFQSxJQUFJLENBQUNXLFNBQVNZLEVBQUUsRUFBRTtZQUNoQixNQUFNQyxRQUFRLE1BQU1iLFNBQVNQLElBQUk7WUFDakMsTUFBTSxJQUFJTSxNQUFNLENBQUMsa0JBQWtCLEVBQUVDLFNBQVNjLE1BQU0sQ0FBQyxHQUFHLEVBQUVELE9BQU87UUFDbkU7UUFFQSxNQUFNRSxPQUFPLE1BQU1mLFNBQVNnQixJQUFJO1FBRWhDLE9BQU9ELEtBQUtBLElBQUksQ0FBQ0UsR0FBRyxDQUFDLENBQUNDLE9BQW1DLENBQUE7Z0JBQ3ZEQyxXQUFXRCxLQUFLQyxTQUFTO2dCQUN6QlQsT0FBT2YsYUFBYWUsS0FBSztnQkFDekJVLFlBQVlMLEtBQUtNLEtBQUssRUFBRUMsZ0JBQWdCO1lBQzFDLENBQUE7SUFDRjtJQUVBOztHQUVDLEdBQ0QsTUFBYy9CLFlBQVlKLEtBQWUsRUFBOEI7UUFDckUsTUFBTW9DLGVBQWUsSUFBSSxDQUFDM0MsTUFBTSxDQUFDRSxNQUFNO1FBRXZDLGtEQUFrRDtRQUNsRCxNQUFNYyxTQUFTMkIsYUFBYTNCLE1BQU0sSUFBSW5CLE9BQU9vQixPQUFPLEVBQUUyQjtRQUN0RCxJQUFJLENBQUM1QixRQUFRO1lBQ1gsTUFBTSxJQUFJRyxNQUNSO1FBRUo7UUFFQSxNQUFNQyxXQUFXLE1BQU1DLE1BQU1zQixhQUFhckIsT0FBTyxFQUFFO1lBQ2pEQyxRQUFRO1lBQ1JDLFNBQVM7Z0JBQ1AsZ0JBQWdCO2dCQUNoQkMsZUFBZSxDQUFDLE9BQU8sRUFBRVQsUUFBUTtZQUNuQztZQUNBVSxNQUFNQyxLQUFLQyxTQUFTLENBQUM7Z0JBQ25CQyxPQUFPdEI7Z0JBQ1B1QixPQUFPYSxhQUFhYixLQUFLO1lBQzNCO1FBQ0Y7UUFFQSxJQUFJLENBQUNWLFNBQVNZLEVBQUUsRUFBRTtZQUNoQixNQUFNQyxRQUFRLE1BQU1iLFNBQVNQLElBQUk7WUFDakMsTUFBTSxJQUFJTSxNQUFNLENBQUMsa0JBQWtCLEVBQUVDLFNBQVNjLE1BQU0sQ0FBQyxHQUFHLEVBQUVELE9BQU87UUFDbkU7UUFFQSxNQUFNRSxPQUFPLE1BQU1mLFNBQVNnQixJQUFJO1FBRWhDLE9BQU9ELEtBQUtBLElBQUksQ0FBQ0UsR0FBRyxDQUFDLENBQUNDLE9BQW1DLENBQUE7Z0JBQ3ZEQyxXQUFXRCxLQUFLQyxTQUFTO2dCQUN6QlQsT0FBT2EsYUFBYWIsS0FBSztnQkFDekJVLFlBQVlMLEtBQUtNLEtBQUssRUFBRUMsZ0JBQWdCO1lBQzFDLENBQUE7SUFDRjtJQUVBOztHQUVDLEdBQ0QsTUFBTUcsV0FDSnRDLEtBQWUsRUFDZkMsUUFBMkIsRUFDM0JDLFlBQTZCLFVBQVUsRUFDdkNxQyxVQUE2QixFQUNEO1FBQzVCLE1BQU1DLFlBQ0p2QyxhQUFhLFdBQ1QsSUFBSSxDQUFDUixNQUFNLENBQUNDLE1BQU0sQ0FBQzhDLFNBQVMsR0FDNUIsSUFBSSxDQUFDL0MsTUFBTSxDQUFDRSxNQUFNLENBQUM2QyxTQUFTO1FBRWxDLE1BQU1qQyxVQUE2QixFQUFFO1FBRXJDLElBQUssSUFBSWtDLElBQUksR0FBR0EsSUFBSXpDLE1BQU0wQyxNQUFNLEVBQUVELEtBQUtELFVBQVc7WUFDaEQsTUFBTUcsUUFBUTNDLE1BQU00QyxLQUFLLENBQUNILEdBQUdBLElBQUlEO1lBQ2pDLE1BQU1LLGVBQWUsTUFBTSxJQUFJLENBQUM5QyxLQUFLLENBQUM0QyxPQUFPMUMsVUFBVUM7WUFDdkRLLFFBQVF1QyxJQUFJLElBQUlEO1lBRWhCTixhQUFhUSxLQUFLQyxHQUFHLENBQUNQLElBQUlELFdBQVd4QyxNQUFNMEMsTUFBTSxHQUFHMUMsTUFBTTBDLE1BQU07WUFFaEUsd0NBQXdDO1lBQ3hDLElBQUlELElBQUlELFlBQVl4QyxNQUFNMEMsTUFBTSxFQUFFO2dCQUNoQyxNQUFNLElBQUksQ0FBQ08sS0FBSyxDQUFDO1lBQ25CO1FBQ0Y7UUFFQSxPQUFPMUM7SUFDVDtJQUVBOztHQUVDLEdBQ0QsT0FBTzJDLGVBQWVsQixTQUFtQixFQUFVO1FBQ2pELE9BQU8sQ0FBQyxDQUFDLEVBQUVBLFVBQVVtQixJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbkM7SUFFQTs7R0FFQyxHQUNEQyxjQUFjbkQsUUFBMkIsRUFBVTtRQUNqRCxPQUFPQSxhQUFhLFdBQ2hCLElBQUksQ0FBQ1IsTUFBTSxDQUFDQyxNQUFNLENBQUMyRCxVQUFVLEdBQzdCLElBQUksQ0FBQzVELE1BQU0sQ0FBQ0UsTUFBTSxDQUFDMEQsVUFBVTtJQUNuQztJQUVRSixNQUFNSyxFQUFVLEVBQWlCO1FBQ3ZDLE9BQU8sSUFBSUMsUUFBUSxDQUFDQyxVQUFZQyxXQUFXRCxTQUFTRjtJQUN0RDtBQUNGIn0=
@@ -0,0 +1,105 @@
1
+ /**
2
+ * pgvector 통합을 위한 타입 정의
3
+ */
4
+ /** 임베딩 제공자 */
5
+ export type EmbeddingProvider = "voyage" | "openai";
6
+ /** 입력 타입 (Voyage AI 전용 - 비대칭 임베딩) */
7
+ export type VectorInputType = "document" | "query";
8
+ /** 임베딩 결과 */
9
+ export interface EmbeddingResult {
10
+ embedding: number[];
11
+ model: string;
12
+ tokenCount: number;
13
+ }
14
+ /** 청크 정보 */
15
+ export interface Chunk {
16
+ index: number;
17
+ text: string;
18
+ startOffset: number;
19
+ endOffset: number;
20
+ }
21
+ /** 벡터 검색 결과 */
22
+ export interface VectorSearchResult<T = Record<string, unknown>> {
23
+ id: number | string;
24
+ similarity: number;
25
+ data: T;
26
+ }
27
+ /** 하이브리드 검색 결과 (Vector + FTS) */
28
+ export interface HybridSearchResult<T = Record<string, unknown>> extends VectorSearchResult<T> {
29
+ vectorScore?: number;
30
+ ftsScore?: number;
31
+ }
32
+ /** 벤치마크 결과 */
33
+ export interface BenchmarkResult {
34
+ provider: EmbeddingProvider;
35
+ embedTime: number;
36
+ searchTime: number;
37
+ results: VectorSearchResult[];
38
+ }
39
+ /** Voyage AI 설정 */
40
+ export interface VoyageConfig {
41
+ apiKey: string;
42
+ baseUrl: string;
43
+ model: string;
44
+ dimensions: number;
45
+ maxTokens: number;
46
+ batchSize: number;
47
+ }
48
+ /** OpenAI 설정 */
49
+ export interface OpenAIConfig {
50
+ apiKey: string;
51
+ baseUrl: string;
52
+ model: string;
53
+ dimensions: number;
54
+ maxTokens: number;
55
+ batchSize: number;
56
+ }
57
+ /** 청킹 설정 */
58
+ export interface ChunkingConfig {
59
+ chunkSize: number;
60
+ chunkOverlap: number;
61
+ minChunkSize: number;
62
+ skipThreshold: number;
63
+ separators: string[];
64
+ }
65
+ /** 검색 설정 */
66
+ export interface SearchConfig {
67
+ defaultLimit: number;
68
+ similarityThreshold: number;
69
+ vectorWeight: number;
70
+ ftsWeight: number;
71
+ }
72
+ /** pgvector 설정 */
73
+ export interface PgvectorConfig {
74
+ iterativeScan: boolean;
75
+ efSearch: number;
76
+ }
77
+ /** 전체 벡터 설정 */
78
+ export interface VectorConfig {
79
+ voyage: VoyageConfig;
80
+ openai: OpenAIConfig;
81
+ chunking: ChunkingConfig;
82
+ search: SearchConfig;
83
+ pgvector: PgvectorConfig;
84
+ }
85
+ /** 벡터 검색 옵션 */
86
+ export interface VectorSearchOptions {
87
+ embeddingColumn?: string;
88
+ limit?: number;
89
+ threshold?: number;
90
+ where?: string;
91
+ }
92
+ /** 하이브리드 검색 옵션 */
93
+ export interface HybridSearchOptions extends VectorSearchOptions {
94
+ vectorWeight?: number;
95
+ ftsWeight?: number;
96
+ ftsColumn?: string;
97
+ }
98
+ /** 임베딩 저장 항목 */
99
+ export interface EmbeddingItem {
100
+ id: number;
101
+ text: string;
102
+ }
103
+ /** 진행률 콜백 */
104
+ export type ProgressCallback = (processed: number, total: number) => void;
105
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/vector/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * pgvector 통합을 위한 타입 정의
3
+ */ /** 임베딩 제공자 */ /** 진행률 콜백 */ export { };
4
+
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92ZWN0b3IvdHlwZXMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBwZ3ZlY3RvciDthrXtlansnYQg7JyE7ZWcIO2DgOyehSDsoJXsnZhcbiAqL1xuXG4vKiog7J6E67Kg65SpIOygnOqzteyekCAqL1xuZXhwb3J0IHR5cGUgRW1iZWRkaW5nUHJvdmlkZXIgPSBcInZveWFnZVwiIHwgXCJvcGVuYWlcIjtcblxuLyoqIOyeheugpSDtg4DsnoUgKFZveWFnZSBBSSDsoITsmqkgLSDruYTrjIDsua0g7J6E67Kg65SpKSAqL1xuZXhwb3J0IHR5cGUgVmVjdG9ySW5wdXRUeXBlID0gXCJkb2N1bWVudFwiIHwgXCJxdWVyeVwiO1xuXG4vKiog7J6E67Kg65SpIOqysOqzvCAqL1xuZXhwb3J0IGludGVyZmFjZSBFbWJlZGRpbmdSZXN1bHQge1xuICBlbWJlZGRpbmc6IG51bWJlcltdO1xuICBtb2RlbDogc3RyaW5nO1xuICB0b2tlbkNvdW50OiBudW1iZXI7XG59XG5cbi8qKiDssq3tgawg7KCV67O0ICovXG5leHBvcnQgaW50ZXJmYWNlIENodW5rIHtcbiAgaW5kZXg6IG51bWJlcjtcbiAgdGV4dDogc3RyaW5nO1xuICBzdGFydE9mZnNldDogbnVtYmVyO1xuICBlbmRPZmZzZXQ6IG51bWJlcjtcbn1cblxuLyoqIOuyoe2EsCDqsoDsg4kg6rKw6rO8ICovXG5leHBvcnQgaW50ZXJmYWNlIFZlY3RvclNlYXJjaFJlc3VsdDxUID0gUmVjb3JkPHN0cmluZywgdW5rbm93bj4+IHtcbiAgaWQ6IG51bWJlciB8IHN0cmluZztcbiAgc2ltaWxhcml0eTogbnVtYmVyO1xuICBkYXRhOiBUO1xufVxuXG4vKiog7ZWY7J2067iM66as65OcIOqygOyDiSDqsrDqs7wgKFZlY3RvciArIEZUUykgKi9cbmV4cG9ydCBpbnRlcmZhY2UgSHlicmlkU2VhcmNoUmVzdWx0PFQgPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj5cbiAgZXh0ZW5kcyBWZWN0b3JTZWFyY2hSZXN1bHQ8VD4ge1xuICB2ZWN0b3JTY29yZT86IG51bWJlcjtcbiAgZnRzU2NvcmU/OiBudW1iZXI7XG59XG5cbi8qKiDrsqTsuZjrp4jtgawg6rKw6rO8ICovXG5leHBvcnQgaW50ZXJmYWNlIEJlbmNobWFya1Jlc3VsdCB7XG4gIHByb3ZpZGVyOiBFbWJlZGRpbmdQcm92aWRlcjtcbiAgZW1iZWRUaW1lOiBudW1iZXI7XG4gIHNlYXJjaFRpbWU6IG51bWJlcjtcbiAgcmVzdWx0czogVmVjdG9yU2VhcmNoUmVzdWx0W107XG59XG5cbi8qKiBWb3lhZ2UgQUkg7ISk7KCVICovXG5leHBvcnQgaW50ZXJmYWNlIFZveWFnZUNvbmZpZyB7XG4gIGFwaUtleTogc3RyaW5nO1xuICBiYXNlVXJsOiBzdHJpbmc7XG4gIG1vZGVsOiBzdHJpbmc7XG4gIGRpbWVuc2lvbnM6IG51bWJlcjtcbiAgbWF4VG9rZW5zOiBudW1iZXI7XG4gIGJhdGNoU2l6ZTogbnVtYmVyO1xufVxuXG4vKiogT3BlbkFJIOyEpOyglSAqL1xuZXhwb3J0IGludGVyZmFjZSBPcGVuQUlDb25maWcge1xuICBhcGlLZXk6IHN0cmluZztcbiAgYmFzZVVybDogc3RyaW5nO1xuICBtb2RlbDogc3RyaW5nO1xuICBkaW1lbnNpb25zOiBudW1iZXI7XG4gIG1heFRva2VuczogbnVtYmVyO1xuICBiYXRjaFNpemU6IG51bWJlcjtcbn1cblxuLyoqIOyyre2CuSDshKTsoJUgKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2h1bmtpbmdDb25maWcge1xuICBjaHVua1NpemU6IG51bWJlcjtcbiAgY2h1bmtPdmVybGFwOiBudW1iZXI7XG4gIG1pbkNodW5rU2l6ZTogbnVtYmVyO1xuICBza2lwVGhyZXNob2xkOiBudW1iZXI7XG4gIHNlcGFyYXRvcnM6IHN0cmluZ1tdO1xufVxuXG4vKiog6rKA7IOJIOyEpOyglSAqL1xuZXhwb3J0IGludGVyZmFjZSBTZWFyY2hDb25maWcge1xuICBkZWZhdWx0TGltaXQ6IG51bWJlcjtcbiAgc2ltaWxhcml0eVRocmVzaG9sZDogbnVtYmVyO1xuICB2ZWN0b3JXZWlnaHQ6IG51bWJlcjtcbiAgZnRzV2VpZ2h0OiBudW1iZXI7XG59XG5cbi8qKiBwZ3ZlY3RvciDshKTsoJUgKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGd2ZWN0b3JDb25maWcge1xuICBpdGVyYXRpdmVTY2FuOiBib29sZWFuO1xuICBlZlNlYXJjaDogbnVtYmVyO1xufVxuXG4vKiog7KCE7LK0IOuyoe2EsCDshKTsoJUgKi9cbmV4cG9ydCBpbnRlcmZhY2UgVmVjdG9yQ29uZmlnIHtcbiAgdm95YWdlOiBWb3lhZ2VDb25maWc7XG4gIG9wZW5haTogT3BlbkFJQ29uZmlnO1xuICBjaHVua2luZzogQ2h1bmtpbmdDb25maWc7XG4gIHNlYXJjaDogU2VhcmNoQ29uZmlnO1xuICBwZ3ZlY3RvcjogUGd2ZWN0b3JDb25maWc7XG59XG5cbi8qKiDrsqHthLAg6rKA7IOJIOyYteyFmCAqL1xuZXhwb3J0IGludGVyZmFjZSBWZWN0b3JTZWFyY2hPcHRpb25zIHtcbiAgZW1iZWRkaW5nQ29sdW1uPzogc3RyaW5nO1xuICBsaW1pdD86IG51bWJlcjtcbiAgdGhyZXNob2xkPzogbnVtYmVyO1xuICB3aGVyZT86IHN0cmluZztcbn1cblxuLyoqIO2VmOydtOu4jOumrOuTnCDqsoDsg4kg7Ji17IWYICovXG5leHBvcnQgaW50ZXJmYWNlIEh5YnJpZFNlYXJjaE9wdGlvbnMgZXh0ZW5kcyBWZWN0b3JTZWFyY2hPcHRpb25zIHtcbiAgdmVjdG9yV2VpZ2h0PzogbnVtYmVyO1xuICBmdHNXZWlnaHQ/OiBudW1iZXI7XG4gIGZ0c0NvbHVtbj86IHN0cmluZztcbn1cblxuLyoqIOyehOuyoOuUqSDsoIDsnqUg7ZWt66qpICovXG5leHBvcnQgaW50ZXJmYWNlIEVtYmVkZGluZ0l0ZW0ge1xuICBpZDogbnVtYmVyO1xuICB0ZXh0OiBzdHJpbmc7XG59XG5cbi8qKiDsp4TtlonrpaAg7L2c67CxICovXG5leHBvcnQgdHlwZSBQcm9ncmVzc0NhbGxiYWNrID0gKHByb2Nlc3NlZDogbnVtYmVyLCB0b3RhbDogbnVtYmVyKSA9PiB2b2lkO1xuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztDQUVDLEdBRUQsWUFBWSxHQW9IWixXQUFXLEdBQ1gsV0FBMEUifQ==
@@ -0,0 +1,47 @@
1
+ import type { Knex } from "knex";
2
+ import { Embedding } from "./embedding";
3
+ import type { EmbeddingItem, EmbeddingProvider, HybridSearchOptions, HybridSearchResult, ProgressCallback, VectorConfig, VectorSearchOptions, VectorSearchResult } from "./types";
4
+ /**
5
+ * 벡터 검색
6
+ * pgvector를 활용한 벡터 검색 및 하이브리드 검색 지원
7
+ */
8
+ export declare class VectorSearch<T = Record<string, unknown>> {
9
+ private db;
10
+ private config;
11
+ private embedding;
12
+ private tableName;
13
+ constructor(db: Knex, tableName: string, config?: Partial<VectorConfig>);
14
+ /**
15
+ * 단일 항목에 임베딩 저장
16
+ */
17
+ saveEmbedding(id: number, text: string, provider: EmbeddingProvider, embeddingColumn?: string): Promise<void>;
18
+ /**
19
+ * 여러 항목에 임베딩 일괄 저장
20
+ */
21
+ saveEmbeddingsBatch(items: EmbeddingItem[], provider: EmbeddingProvider, embeddingColumn?: string, onProgress?: ProgressCallback): Promise<void>;
22
+ /**
23
+ * 벡터 검색 (코사인 유사도)
24
+ */
25
+ search(query: string, provider: EmbeddingProvider, options?: VectorSearchOptions): Promise<VectorSearchResult<T>[]>;
26
+ /**
27
+ * 하이브리드 검색 (Vector + FTS)
28
+ */
29
+ hybridSearch(query: string, provider: EmbeddingProvider, options?: HybridSearchOptions): Promise<HybridSearchResult<T>[]>;
30
+ /**
31
+ * 임베딩 현황 조회
32
+ */
33
+ getEmbeddingStatus(embeddingColumn?: string): Promise<{
34
+ total: number;
35
+ withEmbedding: number;
36
+ withoutEmbedding: number;
37
+ }>;
38
+ /**
39
+ * 임베딩이 없는 항목 ID 조회
40
+ */
41
+ getItemsWithoutEmbedding(embeddingColumn?: string, limit?: number): Promise<number[]>;
42
+ /**
43
+ * Embedding 인스턴스 반환 (고급 사용)
44
+ */
45
+ getEmbedding(): Embedding;
46
+ }
47
+ //# sourceMappingURL=vector-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vector-search.d.ts","sourceRoot":"","sources":["../../src/vector/vector-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAGjC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EACV,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AACH,qBAAa,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACnD,OAAO,CAAC,EAAE,CAAO;IACjB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,SAAS,CAAS;gBAEd,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM;IAa3E;;OAEG;IACG,aAAa,CACjB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,iBAAiB,EAC3B,eAAe,GAAE,MAA4B,GAC5C,OAAO,CAAC,IAAI,CAAC;IAUhB;;OAEG;IACG,mBAAmB,CACvB,KAAK,EAAE,aAAa,EAAE,EACtB,QAAQ,EAAE,iBAAiB,EAC3B,eAAe,GAAE,MAA4B,EAC7C,UAAU,CAAC,EAAE,gBAAgB,GAC5B,OAAO,CAAC,IAAI,CAAC;IAehB;;OAEG;IACG,MAAM,CACV,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;IAyCnC;;OAEG;IACG,YAAY,CAChB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;IAiFnC;;OAEG;IACG,kBAAkB,CAAC,eAAe,GAAE,MAA4B,GAAG,OAAO,CAAC;QAC/E,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;QACtB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IAgBF;;OAEG;IACG,wBAAwB,CAC5B,eAAe,GAAE,MAA4B,EAC7C,KAAK,GAAE,MAAY,GAClB,OAAO,CAAC,MAAM,EAAE,CAAC;IAUpB;;OAEG;IACH,YAAY,IAAI,SAAS;CAG1B"}