@nine-lab/nine-connector 0.1.7 → 0.1.9
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/package.json +1 -1
- package/prompts/query-generator.md +24 -0
- package/prompts/table-filter.md +21 -0
- package/src/core/init.js +40 -3
package/package.json
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
### SQL_GENERATE_PROMPT
|
|
2
|
+
당신은 SQL 생성기입니다. 제공된 테이블의 컬럼 정보를 바탕으로 사용자의 질문에 답하는 최적의 SQL 쿼리를 작성하세요.
|
|
3
|
+
|
|
4
|
+
[선택된 테이블 정보]
|
|
5
|
+
{detailed_schema}
|
|
6
|
+
|
|
7
|
+
[사용자 질문]
|
|
8
|
+
"{question}"
|
|
9
|
+
|
|
10
|
+
[데이터베이스 타입]
|
|
11
|
+
{db_type}
|
|
12
|
+
|
|
13
|
+
[응답 규칙]
|
|
14
|
+
1. 반드시 JSON 형식으로만 응답하세요.
|
|
15
|
+
2. SQL은 {db_type} 문법에 완벽하게 맞아야 하며, 즉시 실행 가능해야 합니다.
|
|
16
|
+
3. 쿼리문 안에 마크다운 코드 블록(```sql)을 포함하지 마세요. 오직 순수 문자열로만 작성하세요.
|
|
17
|
+
4. 사용자가 이해하기 쉽도록 쿼리에 대한 설명(explanation)을 친절하게 작성하세요.
|
|
18
|
+
5. 존재하지 않는 컬럼이나 테이블은 절대 사용하지 마세요.
|
|
19
|
+
|
|
20
|
+
[응답 포맷]
|
|
21
|
+
{{
|
|
22
|
+
"sql": "SELECT ... FROM ... WHERE ...",
|
|
23
|
+
"explanation": "이 쿼리는 어떤 데이터를 어떻게 조회하는지에 대한 설명입니다."
|
|
24
|
+
}}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
### TABLE_FILTER_PROMPT
|
|
2
|
+
당신은 SQL 전문가입니다. 사용자의 질문을 분석하여 데이터베이스에서 조회해야 할 필수 테이블들만 선정하세요.
|
|
3
|
+
|
|
4
|
+
[전체 테이블 목록]
|
|
5
|
+
{schema_summary}
|
|
6
|
+
|
|
7
|
+
[사용자 질문]
|
|
8
|
+
"{question}"
|
|
9
|
+
|
|
10
|
+
[응답 규칙]
|
|
11
|
+
1. 반드시 JSON 형식으로만 응답하세요.
|
|
12
|
+
2. 질문을 해결하기 위해 반드시 참조해야 하는 테이블 이름만 'selected_tables' 배열에 넣으세요.
|
|
13
|
+
3. 만약 질문이 데이터베이스 조회와 관련이 없거나, 제공된 테이블 정보로 답할 수 없다면 'is_executable'을 false로 설정하세요.
|
|
14
|
+
4. 'reasoning' 필드에는 왜 해당 테이블들을 선택했는지 간략하게 설명하세요.
|
|
15
|
+
|
|
16
|
+
[응답 포맷]
|
|
17
|
+
{{
|
|
18
|
+
"reasoning": "선정 이유를 여기에 작성",
|
|
19
|
+
"selected_tables": ["table1", "table2"],
|
|
20
|
+
"is_executable": true
|
|
21
|
+
}}
|
package/src/core/init.js
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url'; // 이 라인이 반드시 있어야 합니다.
|
|
3
4
|
import readline from 'readline';
|
|
4
|
-
import { DEFAULT_PROMPTS } from './prompts.js'; // 분리한 프롬프트 가져오기
|
|
5
|
+
//import { DEFAULT_PROMPTS } from './prompts.js'; // 분리한 프롬프트 가져오기
|
|
6
|
+
|
|
7
|
+
// 현재 파일(init.js)의 위치를 기준으로 패키지 루트의 prompts 폴더 경로 계산
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = path.dirname(__filename);
|
|
10
|
+
// init.js가 src/core/ 밑에 있다면, ../../prompts가 원본 위치가 됩니다.
|
|
11
|
+
const SOURCE_PROMPT_DIR = path.resolve(__dirname, '../../prompts');
|
|
5
12
|
|
|
6
13
|
/**
|
|
7
14
|
* 1. .env 파일 생성 담당 함수
|
|
@@ -10,7 +17,7 @@ async function createEnvFile(rl) {
|
|
|
10
17
|
const questions = [
|
|
11
18
|
{ key: 'SERVER_PORT', label: '1. 커넥터 서버 포트', default: '3000' },
|
|
12
19
|
{ key: 'GEMINI_API_KEY', label: '2. Gemini API Key', default: '' },
|
|
13
|
-
{ key: 'GEMINI_MODEL', label: '3. 사용할 모델', default: 'gemini-
|
|
20
|
+
{ key: 'GEMINI_MODEL', label: '3. 사용할 모델', default: 'gemini-2.5-flash' },
|
|
14
21
|
{ key: 'DB_TYPE', label: '4. DB 종류 (mysql, pg, mariadb)', default: 'mysql' },
|
|
15
22
|
{ key: 'DB_HOST', label: '5. DB 호스트', default: '127.0.0.1' },
|
|
16
23
|
{ key: 'DB_PORT', label: '6. DB 포트', default: '3306' },
|
|
@@ -51,7 +58,7 @@ async function createEnvFile(rl) {
|
|
|
51
58
|
/**
|
|
52
59
|
* 2. 프롬프트 파일(.md) 생성 담당 함수
|
|
53
60
|
*/
|
|
54
|
-
function
|
|
61
|
+
function createPromptFiles2() {
|
|
55
62
|
const promptDir = path.join(process.cwd(), 'prompts');
|
|
56
63
|
|
|
57
64
|
if (!fs.existsSync(promptDir)) {
|
|
@@ -68,6 +75,36 @@ function createPromptFiles() {
|
|
|
68
75
|
console.log('프롬프트 파일(prompts/*.md) 생성이 완료되었습니다.');
|
|
69
76
|
}
|
|
70
77
|
|
|
78
|
+
function createPromptFiles() {
|
|
79
|
+
const targetDir = path.join(process.cwd(), 'prompts');
|
|
80
|
+
|
|
81
|
+
// 사용자의 프로젝트 폴더에 prompts 폴더 생성
|
|
82
|
+
if (!fs.existsSync(targetDir)) {
|
|
83
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const templateFiles = ['table-filter.md', 'query-generator.md'];
|
|
87
|
+
|
|
88
|
+
templateFiles.forEach((filename) => {
|
|
89
|
+
const sourcePath = path.join(SOURCE_PROMPT_DIR, filename);
|
|
90
|
+
const targetPath = path.join(targetDir, filename);
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
if (fs.existsSync(sourcePath)) {
|
|
94
|
+
// 원본을 읽어서 사용자 폴더에 생성 (개행 문자 보장)
|
|
95
|
+
const content = fs.readFileSync(sourcePath, 'utf-8');
|
|
96
|
+
fs.writeFileSync(targetPath, content.trim() + '\n', 'utf-8');
|
|
97
|
+
} else {
|
|
98
|
+
console.error(`원본 템플릿을 찾을 수 없습니다: ${sourcePath}`);
|
|
99
|
+
}
|
|
100
|
+
} catch (err) {
|
|
101
|
+
console.error(`${filename} 생성 중 오류 발생:`, err.message);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
console.log('프롬프트 파일(prompts/*.md) 생성이 완료되었습니다.');
|
|
106
|
+
}
|
|
107
|
+
|
|
71
108
|
/**
|
|
72
109
|
* 메인 실행 함수
|
|
73
110
|
*/
|