@ilivemylife/graph-sdk 1.0.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 +725 -0
- package/bin/ilml +5 -0
- package/dist/cli.mjs +2890 -0
- package/dist/client.cjs +1212 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.cts +607 -0
- package/dist/client.d.ts +607 -0
- package/dist/client.mjs +1138 -0
- package/dist/client.mjs.map +1 -0
- package/dist/mcp-server.mjs +1957 -0
- package/dist/queries.cjs +443 -0
- package/dist/queries.cjs.map +1 -0
- package/dist/queries.d.cts +201 -0
- package/dist/queries.d.ts +201 -0
- package/dist/queries.mjs +383 -0
- package/dist/queries.mjs.map +1 -0
- package/examples/README.md +143 -0
- package/examples/ask-lifebot.mjs +43 -0
- package/examples/error-handling.mjs +89 -0
- package/examples/getting-started.mjs +201 -0
- package/examples/manage-items.mjs +78 -0
- package/examples/messenger-basics.mjs +189 -0
- package/examples/subscriptions.mjs +60 -0
- package/package.json +68 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Messenger Basics - Messages and Lifebot
|
|
3
|
+
*
|
|
4
|
+
* Shows how to work with the messenger in nodes:
|
|
5
|
+
* - Send messages (without AI)
|
|
6
|
+
* - Read messages
|
|
7
|
+
* - Ask Lifebot and wait for response
|
|
8
|
+
* - Ask Lifebot to create/organize nodes
|
|
9
|
+
*
|
|
10
|
+
* Getting your token:
|
|
11
|
+
* Option 1: npx ilml login
|
|
12
|
+
* Option 2: Browser DevTools → Network tab → any request → Headers → "access-token"
|
|
13
|
+
*
|
|
14
|
+
* Run:
|
|
15
|
+
* node examples/messenger-basics.mjs
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import {
|
|
19
|
+
createGraphClient,
|
|
20
|
+
LIFEBOT_MESSAGE_TYPES,
|
|
21
|
+
LifebotTimeoutError,
|
|
22
|
+
LifebotRateLimitError
|
|
23
|
+
} from '@ilivemylife/graph-sdk';
|
|
24
|
+
|
|
25
|
+
const graph = createGraphClient({
|
|
26
|
+
token: process.env.ILML_TOKEN
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
console.log('='.repeat(60));
|
|
30
|
+
console.log('Messenger & Lifebot Example');
|
|
31
|
+
console.log('='.repeat(60));
|
|
32
|
+
|
|
33
|
+
// Get user's root node for demos
|
|
34
|
+
const me = await graph.me();
|
|
35
|
+
console.log('\nUsing root node:', me.rootItemId);
|
|
36
|
+
|
|
37
|
+
// ============================================================================
|
|
38
|
+
// 1. Read existing messages
|
|
39
|
+
// ============================================================================
|
|
40
|
+
|
|
41
|
+
console.log('\n[Reading Messages]');
|
|
42
|
+
const messages = await graph.messages(me.rootItemId, 5);
|
|
43
|
+
console.log(`Found ${messages.length} messages`);
|
|
44
|
+
|
|
45
|
+
messages.forEach(msg => {
|
|
46
|
+
const date = new Date(parseInt(msg.createdAt)).toLocaleString();
|
|
47
|
+
const preview = msg.content?.substring(0, 50) || '(empty)';
|
|
48
|
+
console.log(` [${date}] ${msg.createdBy}: ${preview}...`);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// ============================================================================
|
|
52
|
+
// 2. Send a simple message (no AI response)
|
|
53
|
+
// ============================================================================
|
|
54
|
+
|
|
55
|
+
console.log('\n[Sending Message - No AI]');
|
|
56
|
+
const simpleMsg = await graph.addMessage(me.rootItemId, 'Hello from SDK! This is a test message.', {
|
|
57
|
+
lifebot: LIFEBOT_MESSAGE_TYPES.off // Don't trigger AI response
|
|
58
|
+
});
|
|
59
|
+
console.log(' Sent message ID:', simpleMsg.id);
|
|
60
|
+
console.log(' Content:', simpleMsg.content);
|
|
61
|
+
|
|
62
|
+
// ============================================================================
|
|
63
|
+
// 3. Ask Lifebot a simple question
|
|
64
|
+
// ============================================================================
|
|
65
|
+
|
|
66
|
+
console.log('\n[Asking Lifebot - Simple Question]');
|
|
67
|
+
console.log(' Sending: "What is 2 + 2?"');
|
|
68
|
+
console.log(' Waiting for AI response...');
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
const answer = await graph.askLifebot(me.rootItemId, 'What is 2 + 2?', {
|
|
72
|
+
timeout: 60000 // Wait up to 60 seconds
|
|
73
|
+
});
|
|
74
|
+
console.log(' Lifebot says:', answer.content);
|
|
75
|
+
} catch (error) {
|
|
76
|
+
if (error instanceof LifebotTimeoutError) {
|
|
77
|
+
console.log(' Timeout - Lifebot did not respond in time');
|
|
78
|
+
console.log(' (Check if Lifebot is enabled in node settings)');
|
|
79
|
+
} else if (error instanceof LifebotRateLimitError) {
|
|
80
|
+
console.log(' Rate limit exceeded, try again later');
|
|
81
|
+
} else {
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ============================================================================
|
|
87
|
+
// 4. Ask Lifebot to search/analyze
|
|
88
|
+
// ============================================================================
|
|
89
|
+
|
|
90
|
+
console.log('\n[Asking Lifebot - Search in Graph]');
|
|
91
|
+
console.log(' Sending: "What nodes do I have in my root?"');
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
const searchAnswer = await graph.askLifebot(
|
|
95
|
+
me.rootItemId,
|
|
96
|
+
'What nodes do I have in my root? List the first 5.',
|
|
97
|
+
{ timeout: 60000 }
|
|
98
|
+
);
|
|
99
|
+
console.log(' Lifebot says:', searchAnswer.content.substring(0, 200) + '...');
|
|
100
|
+
} catch (error) {
|
|
101
|
+
if (error instanceof LifebotTimeoutError) {
|
|
102
|
+
console.log(' Timeout - try with a longer timeout or check Lifebot settings');
|
|
103
|
+
} else {
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ============================================================================
|
|
109
|
+
// 5. Ask Lifebot to CREATE a node
|
|
110
|
+
// ============================================================================
|
|
111
|
+
|
|
112
|
+
console.log('\n[Asking Lifebot - Create Node]');
|
|
113
|
+
console.log(' Asking Lifebot to create a project node...');
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
const createResult = await graph.askLifebot(
|
|
117
|
+
me.rootItemId,
|
|
118
|
+
`Please create a new node called "Lifebot Demo Project".
|
|
119
|
+
Add a markdown description explaining that this project was created by Lifebot
|
|
120
|
+
as a demonstration of AI capabilities in iLiveMyLife.`,
|
|
121
|
+
{ timeout: 120000 } // 2 minutes for complex operations
|
|
122
|
+
);
|
|
123
|
+
console.log(' Lifebot:', createResult.content.substring(0, 300));
|
|
124
|
+
} catch (error) {
|
|
125
|
+
if (error instanceof LifebotTimeoutError) {
|
|
126
|
+
console.log(' Timeout on create operation');
|
|
127
|
+
} else {
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ============================================================================
|
|
133
|
+
// 6. Ask Lifebot to create STRUCTURE
|
|
134
|
+
// ============================================================================
|
|
135
|
+
|
|
136
|
+
console.log('\n[Asking Lifebot - Create Structure]');
|
|
137
|
+
console.log(' Asking Lifebot to add child nodes to the project...');
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
const structureResult = await graph.askLifebot(
|
|
141
|
+
me.rootItemId,
|
|
142
|
+
`Inside the "Lifebot Demo Project" you just created, please add these child nodes:
|
|
143
|
+
1. "Features" - describe what Lifebot can do
|
|
144
|
+
2. "Examples" - list example use cases
|
|
145
|
+
3. "Getting Started" - how to enable and use Lifebot
|
|
146
|
+
|
|
147
|
+
Add helpful descriptions to each.`,
|
|
148
|
+
{ timeout: 120000 }
|
|
149
|
+
);
|
|
150
|
+
console.log(' Lifebot:', structureResult.content.substring(0, 300));
|
|
151
|
+
} catch (error) {
|
|
152
|
+
if (error instanceof LifebotTimeoutError) {
|
|
153
|
+
console.log(' Timeout on structure operation');
|
|
154
|
+
} else {
|
|
155
|
+
throw error;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ============================================================================
|
|
160
|
+
// Done!
|
|
161
|
+
// ============================================================================
|
|
162
|
+
|
|
163
|
+
console.log('\n' + '='.repeat(60));
|
|
164
|
+
console.log('What is Lifebot?');
|
|
165
|
+
console.log('='.repeat(60));
|
|
166
|
+
console.log(`
|
|
167
|
+
Lifebot is the AI assistant built into iLiveMyLife. It can:
|
|
168
|
+
|
|
169
|
+
- Answer questions about your knowledge graph
|
|
170
|
+
- Search and find information across your nodes
|
|
171
|
+
- CREATE new nodes with titles and descriptions
|
|
172
|
+
- ORGANIZE information by creating structure
|
|
173
|
+
- Execute actions on your behalf
|
|
174
|
+
|
|
175
|
+
When you call askLifebot(), your message is sent to Lifebot which:
|
|
176
|
+
1. Receives your question/request
|
|
177
|
+
2. Has access to the current node's context
|
|
178
|
+
3. Can perform actions (create, edit, etc.)
|
|
179
|
+
4. Sends back a response
|
|
180
|
+
|
|
181
|
+
Tips:
|
|
182
|
+
- Enable Lifebot in node settings (add 'assist' tag)
|
|
183
|
+
- Use clear, specific requests
|
|
184
|
+
- For complex operations, increase timeout
|
|
185
|
+
- Check node settings if Lifebot doesn't respond
|
|
186
|
+
`);
|
|
187
|
+
|
|
188
|
+
// Free resources and close connections
|
|
189
|
+
graph.destroy();
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Real-time Subscriptions Example
|
|
3
|
+
*
|
|
4
|
+
* Shows how to subscribe to message and item changes.
|
|
5
|
+
*
|
|
6
|
+
* Run: node examples/subscriptions.mjs
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
createGraphClient,
|
|
11
|
+
MESSAGE_CHANGE_TYPES,
|
|
12
|
+
ITEM_CHANGE_TYPES
|
|
13
|
+
} from '@ilivemylife/graph-sdk';
|
|
14
|
+
|
|
15
|
+
const graph = createGraphClient({
|
|
16
|
+
token: process.env.ILML_TOKEN
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const nodeId = process.env.NODE_ID;
|
|
20
|
+
|
|
21
|
+
// Subscribe to messages with change type handling
|
|
22
|
+
console.log('Subscribing to messages...');
|
|
23
|
+
const unsubscribeMessages = await graph.subscribeToMessages(nodeId, (change, message) => {
|
|
24
|
+
if (change === MESSAGE_CHANGE_TYPES.added) {
|
|
25
|
+
console.log('New message:', message.content?.substring(0, 50));
|
|
26
|
+
} else if (change === MESSAGE_CHANGE_TYPES.edited) {
|
|
27
|
+
console.log('Message edited:', message.id);
|
|
28
|
+
} else if (change === MESSAGE_CHANGE_TYPES.deleted) {
|
|
29
|
+
console.log('Message deleted:', message.id);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Subscribe to item changes with change type handling
|
|
34
|
+
console.log('Subscribing to items...');
|
|
35
|
+
const unsubscribeItems = await graph.subscribeToItems(nodeId, (change, item) => {
|
|
36
|
+
if (change === ITEM_CHANGE_TYPES.added) {
|
|
37
|
+
console.log('New item:', item.title);
|
|
38
|
+
} else if (change === ITEM_CHANGE_TYPES.edited) {
|
|
39
|
+
console.log('Item edited:', item.title);
|
|
40
|
+
} else if (change === ITEM_CHANGE_TYPES.movedIn) {
|
|
41
|
+
console.log('Item moved here:', item.title);
|
|
42
|
+
} else if (change === ITEM_CHANGE_TYPES.reorder) {
|
|
43
|
+
console.log('Item reordered:', item.title);
|
|
44
|
+
} else if (change === ITEM_CHANGE_TYPES.deleted) {
|
|
45
|
+
console.log('Item deleted:', item.id);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
console.log('Listening for changes... Press Ctrl+C to stop');
|
|
50
|
+
|
|
51
|
+
// Clean up on exit
|
|
52
|
+
process.on('SIGINT', () => {
|
|
53
|
+
console.log('\nUnsubscribing...');
|
|
54
|
+
unsubscribeMessages();
|
|
55
|
+
unsubscribeItems();
|
|
56
|
+
process.exit(0);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Keep process alive
|
|
60
|
+
setInterval(() => {}, 1000);
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ilivemylife/graph-sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "SDK and CLI for iLiveMyLife Knowledge Graph",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=18.0.0"
|
|
8
|
+
},
|
|
9
|
+
"sideEffects": false,
|
|
10
|
+
"type": "module",
|
|
11
|
+
"main": "./dist/client.cjs",
|
|
12
|
+
"module": "./dist/client.mjs",
|
|
13
|
+
"types": "./dist/client.d.ts",
|
|
14
|
+
"bin": {
|
|
15
|
+
"ilml": "./bin/ilml",
|
|
16
|
+
"ilml-mcp": "./dist/mcp-server.mjs"
|
|
17
|
+
},
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/client.d.ts",
|
|
21
|
+
"import": "./dist/client.mjs",
|
|
22
|
+
"require": "./dist/client.cjs"
|
|
23
|
+
},
|
|
24
|
+
"./queries": {
|
|
25
|
+
"types": "./dist/queries.d.ts",
|
|
26
|
+
"import": "./dist/queries.mjs",
|
|
27
|
+
"require": "./dist/queries.cjs"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"bin",
|
|
33
|
+
"examples"
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsup",
|
|
37
|
+
"prepublishOnly": "npm run build",
|
|
38
|
+
"release:patch": "npm version patch && npm publish --access public",
|
|
39
|
+
"release:minor": "npm version minor && npm publish --access public",
|
|
40
|
+
"release:major": "npm version major && npm publish --access public"
|
|
41
|
+
},
|
|
42
|
+
"keywords": [
|
|
43
|
+
"ilivemylife",
|
|
44
|
+
"ilml",
|
|
45
|
+
"knowledge-graph",
|
|
46
|
+
"pkm",
|
|
47
|
+
"graphql",
|
|
48
|
+
"sdk",
|
|
49
|
+
"cli",
|
|
50
|
+
"ai",
|
|
51
|
+
"lifebot"
|
|
52
|
+
],
|
|
53
|
+
"author": "Ilya Sorokin <info@ilivemylife.io> (https://ilivemylife.io)",
|
|
54
|
+
"homepage": "https://ilivemylife.io",
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@apollo/client": "^3.8.0",
|
|
57
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
58
|
+
"cross-fetch": "^4.0.0",
|
|
59
|
+
"graphql": "^16.8.0",
|
|
60
|
+
"graphql-ws": "^5.14.0",
|
|
61
|
+
"ws": "^8.18.0"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@types/ws": "^8.18.1",
|
|
65
|
+
"tsup": "^8.0.0",
|
|
66
|
+
"typescript": "^5.3.0"
|
|
67
|
+
}
|
|
68
|
+
}
|