@youngkang/n8n-nodes-seedos 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,178 @@
1
+ # SeedOS n8n Custom Node
2
+
3
+ SeedOS Memory System을 n8n 워크플로우에 통합하는 Custom Node입니다.
4
+
5
+ ## 🎯 기능
6
+
7
+ - **Store Memory**: 메모리 블록 저장
8
+ - **Search Memory**: 의미 기반 메모리 검색
9
+ - **Query with AI**: Thalamic AI를 사용한 쿼리
10
+ - **Create Identity**: AI Identity 생성
11
+ - **Verify Proof**: Merkle Proof 검증
12
+
13
+ ## 📦 설치
14
+
15
+ ### n8n에서 설치
16
+
17
+ ```bash
18
+ # n8n 커뮤니티 노드로 설치
19
+ npm install @seedos/n8n-nodes-seedos
20
+ ```
21
+
22
+ 또는 n8n UI에서:
23
+ 1. Settings → Community Nodes
24
+ 2. "Install community node" 클릭
25
+ 3. `@seedos/n8n-nodes-seedos` 입력
26
+ 4. Install 클릭
27
+
28
+ ## 🚀 빠른 시작
29
+
30
+ ### 1. SeedOS 서버 준비
31
+
32
+ ```bash
33
+ # Docker로 실행
34
+ docker-compose up -d
35
+
36
+ # 또는 로컬에서 실행
37
+ uvicorn app.api:app --reload
38
+ ```
39
+
40
+ ### 2. n8n에서 노드 사용
41
+
42
+ 1. 워크플로우에 "SeedOS" 노드 추가
43
+ 2. Credentials 설정:
44
+ - **API Key**: `your-secret-api-key-here` (또는 설정한 키)
45
+ - **Base URL**: `http://localhost:8000`
46
+ 3. Operation 선택 (Store, Search, Query, Identity, Proof)
47
+ 4. 파라미터 입력 및 실행
48
+
49
+ ## 📋 Operations
50
+
51
+ ### Store Memory
52
+ 메모리 블록을 저장합니다.
53
+
54
+ **파라미터**:
55
+ - `layer`: 메모리 레이어 (예: "memory")
56
+ - `type`: 블록 타입 (예: "event")
57
+ - `payload`: 저장할 데이터 (JSON 객체)
58
+
59
+ **예시**:
60
+ ```json
61
+ {
62
+ "layer": "memory",
63
+ "type": "event",
64
+ "payload": {
65
+ "text": "Important meeting notes",
66
+ "date": "2026-01-21"
67
+ }
68
+ }
69
+ ```
70
+
71
+ ### Search Memory
72
+ 의미 기반으로 메모리를 검색합니다.
73
+
74
+ **파라미터**:
75
+ - `query`: 검색 쿼리
76
+ - `topK`: 반환할 결과 수 (기본: 5)
77
+
78
+ ### Query with AI
79
+ Thalamic AI를 사용하여 메모리 기반 응답을 생성합니다.
80
+
81
+ **파라미터**:
82
+ - `question`: 질문
83
+ - `llmProvider`: LLM 제공업체 (openai, anthropic)
84
+ - `model`: 모델 이름 (예: "gpt-4")
85
+
86
+ **주의**: LLM API Key가 SeedOS 서버에 설정되어 있어야 합니다.
87
+
88
+ ### Create Identity
89
+ AI Identity를 생성합니다.
90
+
91
+ **파라미터**:
92
+ - `name`: Identity 이름 (영문, 숫자, -, _만 사용)
93
+ - `purpose`: 목적 (최소 10자)
94
+ - `coreValues`: 핵심 가치 (comma-separated)
95
+ - `role`: 역할 (선택)
96
+
97
+ ### Verify Proof
98
+ Merkle Proof를 검증합니다.
99
+
100
+ **파라미터**:
101
+ - `address`: 블록 주소 (MMP 형식)
102
+ - `leafIndex`: 리프 인덱스
103
+ - `leaves`: Merkle tree leaves (JSON 배열)
104
+ - `leafValue`: 검증할 리프 값
105
+
106
+ ## 📚 워크플로우 템플릿
107
+
108
+ 5개의 워크플로우 템플릿이 제공됩니다:
109
+
110
+ 1. **Simple Memory Storage** - 기본 메모리 저장
111
+ 2. **Semantic Memory Search** - 의미 기반 검색
112
+ 3. **AI Memory Assistant** - AI 어시스턴트
113
+ 4. **Identity Management** - Identity 관리
114
+ 5. **Complete Memory Loop** - 완전한 메모리 루프
115
+
116
+ 템플릿은 `workflow_templates/` 디렉토리에 있으며, n8n에서 직접 import할 수 있습니다.
117
+
118
+ 자세한 내용은 [워크플로우 템플릿 가이드](./WORKFLOW_TEMPLATES_README.md)를 참조하세요.
119
+
120
+ ## 🔧 개발
121
+
122
+ ```bash
123
+ # 의존성 설치
124
+ npm install
125
+
126
+ # 빌드
127
+ npm run build
128
+
129
+ # 개발 모드 (watch)
130
+ npm run dev
131
+
132
+ # 린트
133
+ npm run lint
134
+ npm run lintfix
135
+ ```
136
+
137
+ ## 🔗 API 엔드포인트
138
+
139
+ SeedOS API 엔드포인트:
140
+ - `POST /write` - 메모리 블록 저장
141
+ - `POST /search` - 의미 기반 검색
142
+ - `POST /query` - AI 쿼리
143
+ - `POST /identity` - Identity 생성
144
+ - `POST /proof` - Merkle Proof 검증
145
+ - `GET /read` - 메모리 블록 읽기
146
+ - `GET /health` - Health check
147
+
148
+ ## 📖 추가 문서
149
+
150
+ - [워크플로우 템플릿 가이드](./WORKFLOW_TEMPLATES_README.md)
151
+ - [로컬 개발 가이드](./LOCAL_DEVELOPMENT.md)
152
+ - [테스트 가이드](./LOCAL_TEST_GUIDE.md)
153
+ - [npm 발행 가이드](./NPM_PUBLISH_GUIDE.md)
154
+
155
+ ## 🐛 문제 해결
156
+
157
+ ### "Invalid API key" 오류
158
+ - SeedOS 서버가 실행 중인지 확인
159
+ - API Key가 올바른지 확인
160
+ - Credentials 설정 확인
161
+
162
+ ### "Identity not found" 오류
163
+ - Identity가 생성되었는지 확인
164
+ - 필요시 Identity 생성 워크플로우 실행
165
+
166
+ ### "Search failed" 오류
167
+ - Identity가 생성되어 있는지 확인
168
+ - 메모리가 저장되어 있는지 확인
169
+
170
+ ## 📝 라이선스
171
+
172
+ MIT
173
+
174
+ ## 🔗 관련 링크
175
+
176
+ - [SeedOS GitHub](https://github.com/seedos/seedos-mvp)
177
+ - [SeedOS API 문서](https://github.com/seedos/seedos-mvp/blob/main/README.md)
178
+ - [n8n 문서](https://docs.n8n.io/)
@@ -0,0 +1,25 @@
1
+ import { ICredentialType, NodePropertyTypes } from 'n8n-workflow';
2
+ export declare class SeedOSApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ properties: ({
7
+ displayName: string;
8
+ name: string;
9
+ type: NodePropertyTypes;
10
+ typeOptions: {
11
+ password: boolean;
12
+ };
13
+ default: string;
14
+ required: boolean;
15
+ description: string;
16
+ } | {
17
+ displayName: string;
18
+ name: string;
19
+ type: NodePropertyTypes;
20
+ default: string;
21
+ required: boolean;
22
+ description: string;
23
+ typeOptions?: undefined;
24
+ })[];
25
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SeedOSApi = void 0;
4
+ class SeedOSApi {
5
+ constructor() {
6
+ this.name = 'seedosApi';
7
+ this.displayName = 'SeedOS API';
8
+ this.documentationUrl = 'https://github.com/seedos/seedos-mvp';
9
+ this.properties = [
10
+ {
11
+ displayName: 'API Key',
12
+ name: 'apiKey',
13
+ type: 'string',
14
+ typeOptions: {
15
+ password: true,
16
+ },
17
+ default: '',
18
+ required: true,
19
+ description: 'SeedOS API Key',
20
+ },
21
+ {
22
+ displayName: 'Base URL',
23
+ name: 'baseUrl',
24
+ type: 'string',
25
+ default: 'http://localhost:8000',
26
+ required: true,
27
+ description: 'SeedOS API Base URL',
28
+ },
29
+ ];
30
+ }
31
+ }
32
+ exports.SeedOSApi = SeedOSApi;
@@ -0,0 +1,2 @@
1
+ import { IExecuteFunctions, IHttpRequestMethods } from 'n8n-workflow';
2
+ export declare function seedosApiRequest(this: IExecuteFunctions, method: IHttpRequestMethods, endpoint: string, body?: any): Promise<any>;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.seedosApiRequest = void 0;
4
+ async function seedosApiRequest(method, endpoint, body) {
5
+ const credentials = await this.getCredentials('seedosApi');
6
+ const options = {
7
+ method: method,
8
+ url: `${credentials.baseUrl}${endpoint}`,
9
+ headers: {
10
+ 'X-API-Key': credentials.apiKey,
11
+ 'Content-Type': 'application/json',
12
+ },
13
+ };
14
+ if (body) {
15
+ options.body = JSON.stringify(body);
16
+ }
17
+ const response = await this.helpers.httpRequest(options);
18
+ return response;
19
+ }
20
+ exports.seedosApiRequest = seedosApiRequest;
@@ -0,0 +1,5 @@
1
+ import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
+ export declare class SeedOS implements INodeType {
3
+ description: INodeTypeDescription;
4
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
5
+ }
@@ -0,0 +1,303 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SeedOS = void 0;
4
+ const GenericFunctions_1 = require("./GenericFunctions");
5
+ class SeedOS {
6
+ constructor() {
7
+ this.description = {
8
+ displayName: 'SeedOS',
9
+ name: 'seedos',
10
+ icon: 'file:seedos.svg',
11
+ group: ['transform'],
12
+ version: 1,
13
+ subtitle: '={{$parameter["operation"]}}',
14
+ description: 'AI Memory System with Identity and Semantic Search',
15
+ defaults: {
16
+ name: 'SeedOS',
17
+ },
18
+ inputs: ['main'],
19
+ outputs: ['main'],
20
+ credentials: [
21
+ {
22
+ name: 'seedosApi',
23
+ required: true,
24
+ },
25
+ ],
26
+ properties: [
27
+ {
28
+ displayName: 'Operation',
29
+ name: 'operation',
30
+ type: 'options',
31
+ noDataExpression: true,
32
+ options: [
33
+ {
34
+ name: 'Store Memory',
35
+ value: 'store',
36
+ description: 'Store a memory block',
37
+ action: 'Store a memory block',
38
+ },
39
+ {
40
+ name: 'Search Memory',
41
+ value: 'search',
42
+ description: 'Search memories semantically',
43
+ action: 'Search memories semantically',
44
+ },
45
+ {
46
+ name: 'Query with AI',
47
+ value: 'query',
48
+ description: 'Query with Thalamic AI',
49
+ action: 'Query with Thalamic AI',
50
+ },
51
+ {
52
+ name: 'Create Identity',
53
+ value: 'identity',
54
+ description: 'Create AI identity',
55
+ action: 'Create AI identity',
56
+ },
57
+ {
58
+ name: 'Verify Proof',
59
+ value: 'proof',
60
+ description: 'Verify Merkle proof',
61
+ action: 'Verify Merkle proof',
62
+ },
63
+ ],
64
+ default: 'store',
65
+ },
66
+ // Store Memory fields
67
+ {
68
+ displayName: 'Layer',
69
+ name: 'layer',
70
+ type: 'string',
71
+ displayOptions: {
72
+ show: {
73
+ operation: ['store'],
74
+ },
75
+ },
76
+ default: 'memory',
77
+ required: true,
78
+ description: 'Memory layer (e.g., memory, identity)',
79
+ },
80
+ {
81
+ displayName: 'Type',
82
+ name: 'type',
83
+ type: 'string',
84
+ displayOptions: {
85
+ show: {
86
+ operation: ['store'],
87
+ },
88
+ },
89
+ default: 'event',
90
+ required: true,
91
+ description: 'Block type (e.g., event, judgment)',
92
+ },
93
+ {
94
+ displayName: 'Payload',
95
+ name: 'payload',
96
+ type: 'json',
97
+ displayOptions: {
98
+ show: {
99
+ operation: ['store'],
100
+ },
101
+ },
102
+ default: '{}',
103
+ required: true,
104
+ description: 'Memory payload (JSON object)',
105
+ },
106
+ // Search Memory fields
107
+ {
108
+ displayName: 'Query',
109
+ name: 'query',
110
+ type: 'string',
111
+ displayOptions: {
112
+ show: {
113
+ operation: ['search'],
114
+ },
115
+ },
116
+ default: '',
117
+ required: true,
118
+ description: 'Search query text',
119
+ },
120
+ {
121
+ displayName: 'Top K',
122
+ name: 'topK',
123
+ type: 'number',
124
+ displayOptions: {
125
+ show: {
126
+ operation: ['search'],
127
+ },
128
+ },
129
+ default: 5,
130
+ description: 'Number of results to return',
131
+ },
132
+ // Query with AI fields
133
+ {
134
+ displayName: 'Question',
135
+ name: 'question',
136
+ type: 'string',
137
+ displayOptions: {
138
+ show: {
139
+ operation: ['query'],
140
+ },
141
+ },
142
+ default: '',
143
+ required: true,
144
+ description: 'Question to ask the AI',
145
+ },
146
+ {
147
+ displayName: 'LLM Provider',
148
+ name: 'llmProvider',
149
+ type: 'options',
150
+ displayOptions: {
151
+ show: {
152
+ operation: ['query'],
153
+ },
154
+ },
155
+ options: [
156
+ { name: 'OpenAI', value: 'openai' },
157
+ { name: 'Anthropic', value: 'anthropic' },
158
+ ],
159
+ default: 'openai',
160
+ description: 'LLM provider',
161
+ },
162
+ {
163
+ displayName: 'Model',
164
+ name: 'model',
165
+ type: 'string',
166
+ displayOptions: {
167
+ show: {
168
+ operation: ['query'],
169
+ },
170
+ },
171
+ default: 'gpt-4',
172
+ description: 'Model name',
173
+ },
174
+ // Proof fields
175
+ {
176
+ displayName: 'Address',
177
+ name: 'address',
178
+ type: 'string',
179
+ displayOptions: {
180
+ show: {
181
+ operation: ['proof'],
182
+ },
183
+ },
184
+ default: '',
185
+ required: true,
186
+ description: 'Block address (MMP format)',
187
+ },
188
+ {
189
+ displayName: 'Leaf Index',
190
+ name: 'leafIndex',
191
+ type: 'number',
192
+ displayOptions: {
193
+ show: {
194
+ operation: ['proof'],
195
+ },
196
+ },
197
+ default: 0,
198
+ description: 'Leaf index in Merkle tree',
199
+ },
200
+ {
201
+ displayName: 'Leaves',
202
+ name: 'leaves',
203
+ type: 'string',
204
+ displayOptions: {
205
+ show: {
206
+ operation: ['proof'],
207
+ },
208
+ },
209
+ default: '[]',
210
+ description: 'Merkle tree leaves (JSON array)',
211
+ },
212
+ {
213
+ displayName: 'Leaf Value',
214
+ name: 'leafValue',
215
+ type: 'string',
216
+ displayOptions: {
217
+ show: {
218
+ operation: ['proof'],
219
+ },
220
+ },
221
+ default: '',
222
+ description: 'Leaf value to verify',
223
+ },
224
+ ],
225
+ };
226
+ }
227
+ async execute() {
228
+ const items = this.getInputData();
229
+ const returnData = [];
230
+ const operation = this.getNodeParameter('operation', 0);
231
+ for (let i = 0; i < items.length; i++) {
232
+ try {
233
+ let responseData;
234
+ switch (operation) {
235
+ case 'store':
236
+ responseData = await GenericFunctions_1.seedosApiRequest.call(this, 'POST', '/write', {
237
+ layer: this.getNodeParameter('layer', i),
238
+ type: this.getNodeParameter('type', i),
239
+ payload: JSON.parse(this.getNodeParameter('payload', i)),
240
+ });
241
+ break;
242
+ case 'search':
243
+ responseData = await GenericFunctions_1.seedosApiRequest.call(this, 'POST', '/search', {
244
+ query: this.getNodeParameter('query', i),
245
+ top_k: this.getNodeParameter('topK', i),
246
+ });
247
+ break;
248
+ case 'query':
249
+ responseData = await GenericFunctions_1.seedosApiRequest.call(this, 'POST', '/query', {
250
+ question: this.getNodeParameter('question', i),
251
+ llm_provider: this.getNodeParameter('llmProvider', i),
252
+ model: this.getNodeParameter('model', i),
253
+ });
254
+ break;
255
+ case 'identity':
256
+ const name = this.getNodeParameter('name', i);
257
+ const purpose = this.getNodeParameter('purpose', i);
258
+ const coreValuesStr = this.getNodeParameter('coreValues', i) || 'helpfulness, accuracy, privacy';
259
+ const coreValues = coreValuesStr.split(',').map((v) => v.trim()).filter((v) => v.length > 0);
260
+ const role = this.getNodeParameter('role', i) || 'SeedOS';
261
+ responseData = await GenericFunctions_1.seedosApiRequest.call(this, 'POST', '/identity', {
262
+ name,
263
+ purpose,
264
+ core_values: coreValues.length > 0 ? coreValues : ['helpfulness', 'accuracy', 'privacy'],
265
+ role,
266
+ });
267
+ break;
268
+ case 'proof':
269
+ responseData = await GenericFunctions_1.seedosApiRequest.call(this, 'POST', '/proof', {
270
+ address: this.getNodeParameter('address', i),
271
+ leaf_index: this.getNodeParameter('leafIndex', i),
272
+ leaves: JSON.parse(this.getNodeParameter('leaves', i)),
273
+ leaf_value: this.getNodeParameter('leafValue', i),
274
+ });
275
+ break;
276
+ default:
277
+ throw new Error(`Unknown operation: ${operation}`);
278
+ }
279
+ returnData.push({
280
+ json: responseData,
281
+ pairedItem: {
282
+ item: i,
283
+ },
284
+ });
285
+ }
286
+ catch (error) {
287
+ if (this.continueOnFail()) {
288
+ const errorMessage = error instanceof Error ? error.message : String(error);
289
+ returnData.push({
290
+ json: { error: errorMessage },
291
+ pairedItem: {
292
+ item: i,
293
+ },
294
+ });
295
+ continue;
296
+ }
297
+ throw error;
298
+ }
299
+ }
300
+ return [returnData];
301
+ }
302
+ }
303
+ exports.SeedOS = SeedOS;
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@youngkang/n8n-nodes-seedos",
3
+ "version": "0.1.0",
4
+ "description": "SeedOS Memory System integration for n8n",
5
+ "keywords": [
6
+ "n8n-community-node-package",
7
+ "seedos",
8
+ "memory",
9
+ "ai",
10
+ "semantic-search"
11
+ ],
12
+ "license": "MIT",
13
+ "homepage": "https://github.com/seedos/seedos-mvp",
14
+ "author": {
15
+ "name": "SeedOS Team"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/seedos/seedos-mvp.git",
20
+ "directory": "integrations/n8n"
21
+ },
22
+ "main": "index.js",
23
+ "scripts": {
24
+ "build": "tsc && gulp build:icons",
25
+ "dev": "tsc --watch",
26
+ "format": "prettier nodes credentials --write",
27
+ "lint": "eslint \"nodes/**/*.ts\" \"credentials/**/*.ts\" package.json || true",
28
+ "lintfix": "eslint \"nodes/**/*.ts\" \"credentials/**/*.ts\" package.json --fix || true",
29
+ "prepublishOnly": "npm run build"
30
+ },
31
+ "files": [
32
+ "dist"
33
+ ],
34
+ "n8n": {
35
+ "n8nNodesApiVersion": 1,
36
+ "nodes": [
37
+ "dist/nodes/SeedOS/SeedOS.node.js"
38
+ ],
39
+ "credentials": [
40
+ "dist/credentials/SeedOSApi.credentials.js"
41
+ ]
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^18.15.0",
45
+ "@typescript-eslint/parser": "^5.57.0",
46
+ "eslint-plugin-n8n-nodes-base": "^1.11.0",
47
+ "gulp": "^4.0.2",
48
+ "n8n-workflow": "*",
49
+ "prettier": "^2.8.8",
50
+ "typescript": "~5.1.6"
51
+ },
52
+ "dependencies": {
53
+ "n8n-workflow": "*"
54
+ },
55
+ "peerDependencies": {
56
+ "n8n-workflow": "*"
57
+ }
58
+ }