sonamu 0.7.11 → 0.7.13

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 (153) hide show
  1. package/dist/api/config.d.ts +10 -6
  2. package/dist/api/config.d.ts.map +1 -1
  3. package/dist/api/config.js +2 -1
  4. package/dist/api/sonamu.d.ts +4 -0
  5. package/dist/api/sonamu.d.ts.map +1 -1
  6. package/dist/api/sonamu.js +49 -5
  7. package/dist/bin/cli.js +118 -170
  8. package/dist/database/base-model.d.ts +10 -50
  9. package/dist/database/base-model.d.ts.map +1 -1
  10. package/dist/database/base-model.js +19 -84
  11. package/dist/database/base-model.types.d.ts +4 -4
  12. package/dist/database/base-model.types.d.ts.map +1 -1
  13. package/dist/database/base-model.types.js +1 -1
  14. package/dist/database/db.d.ts +1 -0
  15. package/dist/database/db.d.ts.map +1 -1
  16. package/dist/database/db.js +24 -13
  17. package/dist/database/puri-subset.test-d.js +1 -1
  18. package/dist/database/puri-subset.types.d.ts +1 -0
  19. package/dist/database/puri-subset.types.d.ts.map +1 -1
  20. package/dist/database/puri-subset.types.js +2 -2
  21. package/dist/database/puri.d.ts +82 -3
  22. package/dist/database/puri.d.ts.map +1 -1
  23. package/dist/database/puri.js +180 -14
  24. package/dist/database/puri.types.d.ts +33 -6
  25. package/dist/database/puri.types.d.ts.map +1 -1
  26. package/dist/database/puri.types.js +1 -1
  27. package/dist/database/puri.types.test-d.js +1 -1
  28. package/dist/entity/entity-manager.d.ts +5 -4
  29. package/dist/entity/entity-manager.d.ts.map +1 -1
  30. package/dist/entity/entity-manager.js +8 -1
  31. package/dist/index.d.ts +1 -1
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +3 -3
  34. package/dist/migration/code-generation.d.ts.map +1 -1
  35. package/dist/migration/code-generation.js +33 -2
  36. package/dist/migration/postgresql-schema-reader.d.ts.map +1 -1
  37. package/dist/migration/postgresql-schema-reader.js +53 -22
  38. package/dist/naite/messaging-types.d.ts.map +1 -1
  39. package/dist/naite/messaging-types.js +1 -1
  40. package/dist/naite/naite.js +2 -2
  41. package/dist/stream/sse.d.ts +2 -6
  42. package/dist/stream/sse.d.ts.map +1 -1
  43. package/dist/stream/sse.js +9 -3
  44. package/dist/syncer/api-parser.d.ts.map +1 -1
  45. package/dist/syncer/api-parser.js +7 -2
  46. package/dist/syncer/file-patterns.d.ts +1 -1
  47. package/dist/syncer/file-patterns.d.ts.map +1 -1
  48. package/dist/syncer/file-patterns.js +6 -5
  49. package/dist/syncer/module-loader.d.ts +5 -0
  50. package/dist/syncer/module-loader.d.ts.map +1 -1
  51. package/dist/syncer/module-loader.js +17 -1
  52. package/dist/syncer/syncer.d.ts +5 -1
  53. package/dist/syncer/syncer.d.ts.map +1 -1
  54. package/dist/syncer/syncer.js +28 -19
  55. package/dist/tasks/decorator.d.ts +26 -0
  56. package/dist/tasks/decorator.d.ts.map +1 -0
  57. package/dist/tasks/decorator.js +28 -0
  58. package/dist/tasks/step-wrapper.d.ts +18 -0
  59. package/dist/tasks/step-wrapper.d.ts.map +1 -0
  60. package/dist/tasks/step-wrapper.js +38 -0
  61. package/dist/tasks/workflow-manager.d.ts +40 -0
  62. package/dist/tasks/workflow-manager.d.ts.map +1 -0
  63. package/dist/tasks/workflow-manager.js +193 -0
  64. package/dist/template/implementations/generated.template.d.ts.map +1 -1
  65. package/dist/template/implementations/generated.template.js +7 -3
  66. package/dist/types/types.d.ts +26 -10
  67. package/dist/types/types.d.ts.map +1 -1
  68. package/dist/types/types.js +15 -2
  69. package/dist/ui/ai-api.d.ts +1 -0
  70. package/dist/ui/ai-api.d.ts.map +1 -0
  71. package/dist/ui/ai-api.js +50 -0
  72. package/dist/ui/ai-client.d.ts +1 -0
  73. package/dist/ui/ai-client.d.ts.map +1 -0
  74. package/dist/ui/ai-client.js +438 -0
  75. package/dist/ui/api.d.ts +3 -0
  76. package/dist/ui/api.d.ts.map +1 -0
  77. package/dist/ui/api.js +680 -0
  78. package/dist/ui-web/assets/brand-icons-Cu_C0hZ4.svg +1008 -0
  79. package/dist/ui-web/assets/brand-icons-F3SPCeH1.woff +0 -0
  80. package/dist/ui-web/assets/brand-icons-XL9sxUpA.woff2 +0 -0
  81. package/dist/ui-web/assets/brand-icons-sqJ2Pg7a.eot +0 -0
  82. package/dist/ui-web/assets/brand-icons-ubhWoxly.ttf +0 -0
  83. package/dist/ui-web/assets/flags-DOLqOU7Y.png +0 -0
  84. package/dist/ui-web/assets/icons-BOCtAERH.woff +0 -0
  85. package/dist/ui-web/assets/icons-CHzK1VD9.eot +0 -0
  86. package/dist/ui-web/assets/icons-D29ZQHHw.ttf +0 -0
  87. package/dist/ui-web/assets/icons-Du6TOHnR.woff2 +0 -0
  88. package/dist/ui-web/assets/icons-RwhydX30.svg +1518 -0
  89. package/dist/ui-web/assets/index-CpaB9P6g.css +1 -0
  90. package/dist/ui-web/assets/index-J9MCfjCd.js +95 -0
  91. package/dist/ui-web/assets/outline-icons-BfdLr8tr.svg +366 -0
  92. package/dist/ui-web/assets/outline-icons-DD8jm0uy.ttf +0 -0
  93. package/dist/ui-web/assets/outline-icons-DInHoiqI.woff2 +0 -0
  94. package/dist/ui-web/assets/outline-icons-LX8adJ4n.eot +0 -0
  95. package/dist/ui-web/assets/outline-icons-aQ88nltS.woff +0 -0
  96. package/dist/ui-web/assets/provider-utils_false-BKJD46kk.js +1 -0
  97. package/dist/ui-web/assets/provider-utils_false-Bu5lmX18.js +1 -0
  98. package/dist/ui-web/index.html +13 -0
  99. package/dist/ui-web/vite.svg +1 -0
  100. package/dist/utils/formatter.d.ts.map +1 -1
  101. package/dist/utils/formatter.js +10 -2
  102. package/dist/utils/model.d.ts +9 -2
  103. package/dist/utils/model.d.ts.map +1 -1
  104. package/dist/utils/model.js +16 -1
  105. package/dist/utils/type-utils.d.ts.map +1 -1
  106. package/dist/utils/type-utils.js +3 -1
  107. package/dist/vector/embedding.d.ts +2 -5
  108. package/dist/vector/embedding.d.ts.map +1 -1
  109. package/dist/vector/embedding.js +9 -13
  110. package/dist/vector/types.d.ts.map +1 -1
  111. package/dist/vector/types.js +1 -1
  112. package/package.json +9 -5
  113. package/src/api/config.ts +15 -11
  114. package/src/api/sonamu.ts +60 -6
  115. package/src/bin/cli.ts +57 -119
  116. package/src/database/base-model.ts +21 -128
  117. package/src/database/base-model.types.ts +3 -4
  118. package/src/database/db.ts +28 -18
  119. package/src/database/puri-subset.test-d.ts +1 -0
  120. package/src/database/puri-subset.types.ts +2 -0
  121. package/src/database/puri.ts +238 -27
  122. package/src/database/puri.types.test-d.ts +1 -1
  123. package/src/database/puri.types.ts +49 -6
  124. package/src/entity/entity-manager.ts +9 -0
  125. package/src/index.ts +1 -1
  126. package/src/migration/code-generation.ts +40 -1
  127. package/src/migration/postgresql-schema-reader.ts +53 -22
  128. package/src/naite/messaging-types.ts +43 -44
  129. package/src/naite/naite.ts +1 -1
  130. package/src/shared/app.shared.ts.txt +13 -0
  131. package/src/shared/web.shared.ts.txt +13 -0
  132. package/src/stream/sse.ts +15 -3
  133. package/src/syncer/api-parser.ts +6 -1
  134. package/src/syncer/file-patterns.ts +11 -9
  135. package/src/syncer/module-loader.ts +35 -0
  136. package/src/syncer/syncer.ts +34 -21
  137. package/src/tasks/decorator.ts +71 -0
  138. package/src/tasks/step-wrapper.ts +84 -0
  139. package/src/tasks/workflow-manager.ts +330 -0
  140. package/src/template/implementations/generated.template.ts +19 -6
  141. package/src/types/types.ts +20 -4
  142. package/src/ui/ai-api.ts +60 -0
  143. package/src/ui/ai-client.ts +499 -0
  144. package/src/ui/api.ts +786 -0
  145. package/src/utils/formatter.ts +8 -1
  146. package/src/utils/model.ts +26 -2
  147. package/src/utils/type-utils.ts +2 -0
  148. package/src/vector/embedding.ts +10 -14
  149. package/src/vector/types.ts +1 -2
  150. package/dist/vector/vector-search.d.ts +0 -47
  151. package/dist/vector/vector-search.d.ts.map +0 -1
  152. package/dist/vector/vector-search.js +0 -176
  153. package/src/vector/vector-search.ts +0 -261
@@ -1,261 +0,0 @@
1
- import type { Knex } from "knex";
2
- import pgvector from "pgvector/knex";
3
- import { DEFAULT_VECTOR_CONFIG } from "./config";
4
- import { Embedding } from "./embedding";
5
- import type {
6
- EmbeddingItem,
7
- EmbeddingProvider,
8
- HybridSearchOptions,
9
- HybridSearchResult,
10
- ProgressCallback,
11
- VectorConfig,
12
- VectorSearchOptions,
13
- VectorSearchResult,
14
- } from "./types";
15
-
16
- /**
17
- * 벡터 검색
18
- * pgvector를 활용한 벡터 검색 및 하이브리드 검색 지원
19
- */
20
- export class VectorSearch<T = Record<string, unknown>> {
21
- private db: Knex;
22
- private config: VectorConfig;
23
- private embedding: Embedding;
24
- private tableName: string;
25
-
26
- constructor(db: Knex, tableName: string, config: Partial<VectorConfig> = {}) {
27
- this.db = db;
28
- this.tableName = tableName;
29
- this.config = {
30
- voyage: { ...DEFAULT_VECTOR_CONFIG.voyage, ...config.voyage },
31
- openai: { ...DEFAULT_VECTOR_CONFIG.openai, ...config.openai },
32
- chunking: { ...DEFAULT_VECTOR_CONFIG.chunking, ...config.chunking },
33
- search: { ...DEFAULT_VECTOR_CONFIG.search, ...config.search },
34
- pgvector: { ...DEFAULT_VECTOR_CONFIG.pgvector, ...config.pgvector },
35
- };
36
- this.embedding = new Embedding(config);
37
- }
38
-
39
- /**
40
- * 단일 항목에 임베딩 저장
41
- */
42
- async saveEmbedding(
43
- id: number,
44
- text: string,
45
- provider: EmbeddingProvider,
46
- embeddingColumn: string = "content_embedding",
47
- ): Promise<void> {
48
- const { embedding } = await this.embedding.embedOne(text, provider, "document");
49
-
50
- await this.db(this.tableName)
51
- .where("id", id)
52
- .update({
53
- [embeddingColumn]: pgvector.toSql(embedding),
54
- });
55
- }
56
-
57
- /**
58
- * 여러 항목에 임베딩 일괄 저장
59
- */
60
- async saveEmbeddingsBatch(
61
- items: EmbeddingItem[],
62
- provider: EmbeddingProvider,
63
- embeddingColumn: string = "content_embedding",
64
- onProgress?: ProgressCallback,
65
- ): Promise<void> {
66
- const texts = items.map((item) => item.text);
67
- const embeddings = await this.embedding.embed(texts, provider, "document", onProgress);
68
-
69
- await this.db.transaction(async (trx) => {
70
- for (let i = 0; i < items.length; i++) {
71
- await trx(this.tableName)
72
- .where("id", items[i].id)
73
- .update({
74
- [embeddingColumn]: pgvector.toSql(embeddings[i].embedding),
75
- });
76
- }
77
- });
78
- }
79
-
80
- /**
81
- * 벡터 검색 (코사인 유사도)
82
- */
83
- async search(
84
- query: string,
85
- provider: EmbeddingProvider,
86
- options: VectorSearchOptions = {},
87
- ): Promise<VectorSearchResult<T>[]> {
88
- const {
89
- embeddingColumn = "content_embedding",
90
- limit = this.config.search.defaultLimit,
91
- threshold = this.config.search.similarityThreshold,
92
- where,
93
- } = options;
94
-
95
- // 쿼리 임베딩 (input_type: 'query' 중요!)
96
- const { embedding } = await this.embedding.embedOne(query, provider, "query");
97
-
98
- // pgvector 세션 설정
99
- if (this.config.pgvector.iterativeScan) {
100
- await this.db.raw("SET hnsw.iterative_scan = relaxed_order");
101
- }
102
- await this.db.raw(`SET hnsw.ef_search = ${this.config.pgvector.efSearch}`);
103
-
104
- // 코사인 유사도 = 1 - 코사인 거리
105
- const vectorStr = pgvector.toSql(embedding);
106
- let queryBuilder = this.db(this.tableName)
107
- .select("*")
108
- .select(this.db.raw(`1 - (${embeddingColumn} <=> ?::vector) AS similarity`, [vectorStr]))
109
- .whereNotNull(embeddingColumn)
110
- .orderByRaw(`${embeddingColumn} <=> ?::vector`, [vectorStr])
111
- .limit(limit);
112
-
113
- if (where) {
114
- queryBuilder = queryBuilder.whereRaw(where);
115
- }
116
-
117
- const rows = await queryBuilder;
118
-
119
- return rows
120
- .filter((row: { similarity: number }) => row.similarity >= threshold)
121
- .map((row: T & { similarity: number }) => ({
122
- id: (row as unknown as { id: number }).id,
123
- similarity: parseFloat(String(row.similarity)),
124
- data: row as T,
125
- }));
126
- }
127
-
128
- /**
129
- * 하이브리드 검색 (Vector + FTS)
130
- */
131
- async hybridSearch(
132
- query: string,
133
- provider: EmbeddingProvider,
134
- options: HybridSearchOptions = {},
135
- ): Promise<HybridSearchResult<T>[]> {
136
- const {
137
- embeddingColumn = "content_embedding",
138
- ftsColumn = "content_tsv",
139
- limit = this.config.search.defaultLimit,
140
- vectorWeight = this.config.search.vectorWeight,
141
- ftsWeight = this.config.search.ftsWeight,
142
- } = options;
143
-
144
- const { embedding } = await this.embedding.embedOne(query, provider, "query");
145
- const vectorStr = pgvector.toSql(embedding);
146
-
147
- // pgvector 세션 설정
148
- if (this.config.pgvector.iterativeScan) {
149
- await this.db.raw("SET hnsw.iterative_scan = relaxed_order");
150
- }
151
- await this.db.raw(`SET hnsw.ef_search = ${this.config.pgvector.efSearch}`);
152
-
153
- const sql = `
154
- WITH vector_search AS (
155
- SELECT
156
- id,
157
- ROW_NUMBER() OVER (ORDER BY ${embeddingColumn} <=> ?::vector) AS rank
158
- FROM ${this.tableName}
159
- WHERE ${embeddingColumn} IS NOT NULL
160
- ORDER BY ${embeddingColumn} <=> ?::vector
161
- LIMIT 50
162
- ),
163
- fts_search AS (
164
- SELECT
165
- id,
166
- ROW_NUMBER() OVER (ORDER BY ts_rank(${ftsColumn}, query) DESC) AS rank
167
- FROM ${this.tableName}, plainto_tsquery('simple', ?) query
168
- WHERE ${ftsColumn} @@ query
169
- LIMIT 50
170
- ),
171
- combined AS (
172
- SELECT
173
- COALESCE(v.id, f.id) AS id,
174
- COALESCE(1.0 / (60 + v.rank), 0) AS vector_score,
175
- COALESCE(1.0 / (60 + f.rank), 0) AS fts_score
176
- FROM vector_search v
177
- FULL OUTER JOIN fts_search f ON v.id = f.id
178
- )
179
- SELECT
180
- t.*,
181
- c.vector_score,
182
- c.fts_score,
183
- (c.vector_score * ? + c.fts_score * ?) AS similarity
184
- FROM combined c
185
- JOIN ${this.tableName} t ON c.id = t.id
186
- ORDER BY similarity DESC
187
- LIMIT ?
188
- `;
189
-
190
- const { rows } = await this.db.raw(sql, [
191
- vectorStr,
192
- vectorStr,
193
- query,
194
- vectorWeight,
195
- ftsWeight,
196
- limit,
197
- ]);
198
-
199
- return rows.map(
200
- (
201
- row: T & {
202
- similarity: number;
203
- vector_score: number;
204
- fts_score: number;
205
- },
206
- ) => ({
207
- id: (row as unknown as { id: number }).id,
208
- similarity: parseFloat(String(row.similarity)),
209
- vectorScore: parseFloat(String(row.vector_score)),
210
- ftsScore: parseFloat(String(row.fts_score)),
211
- data: row as T,
212
- }),
213
- );
214
- }
215
-
216
- /**
217
- * 임베딩 현황 조회
218
- */
219
- async getEmbeddingStatus(embeddingColumn: string = "content_embedding"): Promise<{
220
- total: number;
221
- withEmbedding: number;
222
- withoutEmbedding: number;
223
- }> {
224
- const result = await this.db(this.tableName)
225
- .count("* as total")
226
- .count(`${embeddingColumn} as with_embedding`)
227
- .first();
228
-
229
- const total = parseInt(String(result?.total ?? 0), 10);
230
- const withEmbedding = parseInt(String(result?.with_embedding ?? 0), 10);
231
-
232
- return {
233
- total,
234
- withEmbedding,
235
- withoutEmbedding: total - withEmbedding,
236
- };
237
- }
238
-
239
- /**
240
- * 임베딩이 없는 항목 ID 조회
241
- */
242
- async getItemsWithoutEmbedding(
243
- embeddingColumn: string = "content_embedding",
244
- limit: number = 100,
245
- ): Promise<number[]> {
246
- const rows = await this.db(this.tableName)
247
- .select("id")
248
- .whereNull(embeddingColumn)
249
- .orderBy("id")
250
- .limit(limit);
251
-
252
- return rows.map((row: { id: number }) => row.id);
253
- }
254
-
255
- /**
256
- * Embedding 인스턴스 반환 (고급 사용)
257
- */
258
- getEmbedding(): Embedding {
259
- return this.embedding;
260
- }
261
- }