@olane/os 0.8.15 → 0.8.17
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/dist/src/address/address-factory.d.ts +23 -0
- package/dist/src/address/address-factory.d.ts.map +1 -0
- package/dist/src/address/address-factory.js +42 -0
- package/dist/src/address-book/address-book.d.ts +32 -0
- package/dist/src/address-book/address-book.d.ts.map +1 -0
- package/dist/src/address-book/address-book.js +65 -0
- package/dist/src/auth/os-auth-guard.d.ts +20 -0
- package/dist/src/auth/os-auth-guard.d.ts.map +1 -0
- package/dist/src/auth/os-auth-guard.js +39 -0
- package/dist/src/identity/copass-id.d.ts +23 -0
- package/dist/src/identity/copass-id.d.ts.map +1 -0
- package/dist/src/identity/copass-id.js +37 -0
- package/dist/src/index.d.ts +12 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +12 -0
- package/dist/src/lifecycle/os-lifecycle.d.ts +36 -0
- package/dist/src/lifecycle/os-lifecycle.d.ts.map +1 -0
- package/dist/src/lifecycle/os-lifecycle.js +99 -0
- package/dist/src/mcp/os-mcp-server.d.ts +29 -0
- package/dist/src/mcp/os-mcp-server.d.ts.map +1 -0
- package/dist/src/mcp/os-mcp-server.js +244 -0
- package/dist/src/memory/memory-harness.d.ts +38 -0
- package/dist/src/memory/memory-harness.d.ts.map +1 -0
- package/dist/src/memory/memory-harness.js +100 -0
- package/dist/src/nodes/relay-node.d.ts +31 -0
- package/dist/src/nodes/relay-node.d.ts.map +1 -0
- package/dist/src/nodes/relay-node.js +85 -0
- package/dist/src/o-olane-os/interfaces/o-os.config.d.ts +15 -1
- package/dist/src/o-olane-os/interfaces/o-os.config.d.ts.map +1 -1
- package/dist/src/o-olane-os/o-os.d.ts +22 -0
- package/dist/src/o-olane-os/o-os.d.ts.map +1 -1
- package/dist/src/o-olane-os/o-os.js +109 -9
- package/dist/src/tools/filesystem.tool.d.ts +24 -0
- package/dist/src/tools/filesystem.tool.d.ts.map +1 -0
- package/dist/src/tools/filesystem.tool.js +163 -0
- package/dist/src/utils/config.d.ts +7 -1
- package/dist/src/utils/config.d.ts.map +1 -1
- package/dist/src/utils/config.js +40 -19
- package/dist/src/vector-store/copass-vector-store.tool.d.ts +29 -0
- package/dist/src/vector-store/copass-vector-store.tool.d.ts.map +1 -0
- package/dist/src/vector-store/copass-vector-store.tool.js +152 -0
- package/dist/src/worlds/world-instance.tool.d.ts +30 -0
- package/dist/src/worlds/world-instance.tool.d.ts.map +1 -0
- package/dist/src/worlds/world-instance.tool.js +179 -0
- package/dist/src/worlds/world-manager.tool.d.ts +61 -0
- package/dist/src/worlds/world-manager.tool.d.ts.map +1 -0
- package/dist/src/worlds/world-manager.tool.js +270 -0
- package/dist/src/worlds/world.types.d.ts +23 -0
- package/dist/src/worlds/world.types.d.ts.map +1 -0
- package/dist/src/worlds/world.types.js +1 -0
- package/package.json +15 -14
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OS-level MCP tool definitions.
|
|
3
|
+
*
|
|
4
|
+
* These are meant to be registered on an MCP server by the CLI layer.
|
|
5
|
+
* Each handler receives an OlaneOS instance and returns structured results.
|
|
6
|
+
*/
|
|
7
|
+
import { listOS } from '../lifecycle/os-lifecycle.js';
|
|
8
|
+
import { AddressFactory } from '../address/address-factory.js';
|
|
9
|
+
import { oAddress } from '@olane/o-core';
|
|
10
|
+
function textResult(text) {
|
|
11
|
+
return { content: [{ type: 'text', text }] };
|
|
12
|
+
}
|
|
13
|
+
export const OS_MCP_TOOLS = [
|
|
14
|
+
// ── Lifecycle ──────────────────────────────────────────────
|
|
15
|
+
{
|
|
16
|
+
name: 'os_status',
|
|
17
|
+
description: 'List all OS instances and their status',
|
|
18
|
+
inputSchema: { type: 'object', properties: {} },
|
|
19
|
+
handler: async () => {
|
|
20
|
+
const instances = await listOS();
|
|
21
|
+
return textResult(JSON.stringify(instances, null, 2));
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
// ── Address ────────────────────────────────────────────────
|
|
25
|
+
{
|
|
26
|
+
name: 'address_create',
|
|
27
|
+
description: 'Create a new o:// address',
|
|
28
|
+
inputSchema: {
|
|
29
|
+
type: 'object',
|
|
30
|
+
properties: {
|
|
31
|
+
name: { type: 'string', description: 'Address name' },
|
|
32
|
+
},
|
|
33
|
+
required: ['name'],
|
|
34
|
+
},
|
|
35
|
+
handler: async (params) => {
|
|
36
|
+
const address = AddressFactory.createAddress(params.name);
|
|
37
|
+
return textResult(JSON.stringify({ address: address.value, created: true }));
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'address_list',
|
|
42
|
+
description: 'List all addresses in the address book',
|
|
43
|
+
inputSchema: {
|
|
44
|
+
type: 'object',
|
|
45
|
+
properties: {
|
|
46
|
+
type: {
|
|
47
|
+
type: 'string',
|
|
48
|
+
enum: ['internal', 'external'],
|
|
49
|
+
description: 'Filter by type',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
handler: async (params, ctx) => {
|
|
54
|
+
if (!ctx.addressBook)
|
|
55
|
+
return textResult('Address book not initialized');
|
|
56
|
+
const entries = ctx.addressBook.list(params.type);
|
|
57
|
+
return textResult(JSON.stringify(entries, null, 2));
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
// ── Contacts ───────────────────────────────────────────────
|
|
61
|
+
{
|
|
62
|
+
name: 'contacts_add',
|
|
63
|
+
description: 'Add an address to the address book',
|
|
64
|
+
inputSchema: {
|
|
65
|
+
type: 'object',
|
|
66
|
+
properties: {
|
|
67
|
+
address: { type: 'string', description: 'o:// address' },
|
|
68
|
+
alias: { type: 'string', description: 'Human-friendly alias' },
|
|
69
|
+
type: {
|
|
70
|
+
type: 'string',
|
|
71
|
+
enum: ['internal', 'external'],
|
|
72
|
+
default: 'external',
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
required: ['address'],
|
|
76
|
+
},
|
|
77
|
+
handler: async (params, ctx) => {
|
|
78
|
+
if (!ctx.addressBook)
|
|
79
|
+
return textResult('Address book not initialized');
|
|
80
|
+
await ctx.addressBook.add({
|
|
81
|
+
address: params.address,
|
|
82
|
+
type: params.type || 'external',
|
|
83
|
+
alias: params.alias,
|
|
84
|
+
});
|
|
85
|
+
return textResult(JSON.stringify({ added: true, address: params.address }));
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'contacts_list',
|
|
90
|
+
description: 'List all contacts in the address book',
|
|
91
|
+
inputSchema: { type: 'object', properties: {} },
|
|
92
|
+
handler: async (_params, ctx) => {
|
|
93
|
+
if (!ctx.addressBook)
|
|
94
|
+
return textResult('Address book not initialized');
|
|
95
|
+
return textResult(JSON.stringify(ctx.addressBook.list(), null, 2));
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: 'contacts_remove',
|
|
100
|
+
description: 'Remove an address from the address book',
|
|
101
|
+
inputSchema: {
|
|
102
|
+
type: 'object',
|
|
103
|
+
properties: {
|
|
104
|
+
address: { type: 'string', description: 'o:// address to remove' },
|
|
105
|
+
},
|
|
106
|
+
required: ['address'],
|
|
107
|
+
},
|
|
108
|
+
handler: async (params, ctx) => {
|
|
109
|
+
if (!ctx.addressBook)
|
|
110
|
+
return textResult('Address book not initialized');
|
|
111
|
+
const removed = await ctx.addressBook.remove(params.address);
|
|
112
|
+
return textResult(JSON.stringify({ removed }));
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
// ── Worlds ─────────────────────────────────────────────────
|
|
116
|
+
{
|
|
117
|
+
name: 'world_create',
|
|
118
|
+
description: 'Create a new world (branded network)',
|
|
119
|
+
inputSchema: {
|
|
120
|
+
type: 'object',
|
|
121
|
+
properties: {
|
|
122
|
+
name: { type: 'string', description: 'World name' },
|
|
123
|
+
description: { type: 'string' },
|
|
124
|
+
icon: { type: 'string' },
|
|
125
|
+
supportedTypes: {
|
|
126
|
+
type: 'array',
|
|
127
|
+
items: { type: 'string' },
|
|
128
|
+
description: 'Supported types (default: filepath)',
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
required: ['name'],
|
|
132
|
+
},
|
|
133
|
+
handler: async (params, ctx) => {
|
|
134
|
+
if (!ctx.worldManager)
|
|
135
|
+
return textResult('World manager not initialized');
|
|
136
|
+
const result = await ctx.worldManager.createWorld(params);
|
|
137
|
+
return textResult(JSON.stringify(result, null, 2));
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: 'world_list',
|
|
142
|
+
description: 'List all worlds',
|
|
143
|
+
inputSchema: { type: 'object', properties: {} },
|
|
144
|
+
handler: async (_params, ctx) => {
|
|
145
|
+
if (!ctx.worldManager)
|
|
146
|
+
return textResult('World manager not initialized');
|
|
147
|
+
return textResult(JSON.stringify(ctx.worldManager.listWorlds(), null, 2));
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
name: 'world_join',
|
|
152
|
+
description: 'Join a world by adding your Copass ID',
|
|
153
|
+
inputSchema: {
|
|
154
|
+
type: 'object',
|
|
155
|
+
properties: {
|
|
156
|
+
id: { type: 'string', description: 'World ID' },
|
|
157
|
+
copassId: { type: 'string', description: 'Your Copass ID' },
|
|
158
|
+
},
|
|
159
|
+
required: ['id', 'copassId'],
|
|
160
|
+
},
|
|
161
|
+
handler: async (params, ctx) => {
|
|
162
|
+
if (!ctx.worldManager)
|
|
163
|
+
return textResult('World manager not initialized');
|
|
164
|
+
const result = await ctx.worldManager.joinWorld(params.id, params.copassId);
|
|
165
|
+
return textResult(JSON.stringify(result));
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
// ── Memory ─────────────────────────────────────────────────
|
|
169
|
+
{
|
|
170
|
+
name: 'memory_remember',
|
|
171
|
+
description: 'Ingest a memory into the Copass backend for later retrieval',
|
|
172
|
+
inputSchema: {
|
|
173
|
+
type: 'object',
|
|
174
|
+
properties: {
|
|
175
|
+
key: { type: 'string', description: 'Memory key / entity hint' },
|
|
176
|
+
value: { type: 'string', description: 'Text value to remember' },
|
|
177
|
+
},
|
|
178
|
+
required: ['key', 'value'],
|
|
179
|
+
},
|
|
180
|
+
handler: async (params, ctx) => {
|
|
181
|
+
if (!ctx.memory)
|
|
182
|
+
return textResult('Memory harness not initialized');
|
|
183
|
+
const result = await ctx.memory.remember(params.key, params.value);
|
|
184
|
+
return textResult(JSON.stringify(result));
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
name: 'memory_recall',
|
|
189
|
+
description: 'Query the Copass backend to recall memories',
|
|
190
|
+
inputSchema: {
|
|
191
|
+
type: 'object',
|
|
192
|
+
properties: {
|
|
193
|
+
query: { type: 'string', description: 'Question or topic to recall' },
|
|
194
|
+
},
|
|
195
|
+
required: ['query'],
|
|
196
|
+
},
|
|
197
|
+
handler: async (params, ctx) => {
|
|
198
|
+
if (!ctx.memory)
|
|
199
|
+
return textResult('Memory harness not initialized');
|
|
200
|
+
const result = await ctx.memory.recall(params.query);
|
|
201
|
+
return textResult(JSON.stringify(result));
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
name: 'memory_search',
|
|
206
|
+
description: 'Fast context search across OS memories via Copass',
|
|
207
|
+
inputSchema: {
|
|
208
|
+
type: 'object',
|
|
209
|
+
properties: {
|
|
210
|
+
query: { type: 'string', description: 'Search query' },
|
|
211
|
+
},
|
|
212
|
+
required: ['query'],
|
|
213
|
+
},
|
|
214
|
+
handler: async (params, ctx) => {
|
|
215
|
+
if (!ctx.memory)
|
|
216
|
+
return textResult('Memory harness not initialized');
|
|
217
|
+
const result = await ctx.memory.search(params.query);
|
|
218
|
+
return textResult(JSON.stringify(result));
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
// ── Generic use ────────────────────────────────────────────
|
|
222
|
+
{
|
|
223
|
+
name: 'os_use',
|
|
224
|
+
description: 'Invoke a method on any o:// address in the OS',
|
|
225
|
+
inputSchema: {
|
|
226
|
+
type: 'object',
|
|
227
|
+
properties: {
|
|
228
|
+
address: { type: 'string', description: 'o:// address' },
|
|
229
|
+
method: { type: 'string', description: 'Method name' },
|
|
230
|
+
params: { type: 'object', description: 'Method parameters' },
|
|
231
|
+
},
|
|
232
|
+
required: ['address', 'method'],
|
|
233
|
+
},
|
|
234
|
+
handler: async (params, ctx) => {
|
|
235
|
+
if (!ctx.os)
|
|
236
|
+
return textResult('OS not running');
|
|
237
|
+
const result = await ctx.os.use(new oAddress(params.address), {
|
|
238
|
+
method: params.method,
|
|
239
|
+
params: params.params || {},
|
|
240
|
+
});
|
|
241
|
+
return textResult(JSON.stringify(result, null, 2));
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
];
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MemoryHarness — stores and retrieves OS memory via the Copass backend.
|
|
3
|
+
*
|
|
4
|
+
* - `remember(key, value)` → `olane ingest text` with key as entity hint
|
|
5
|
+
* - `recall(query)` → `olane copass question` scoped to memory context
|
|
6
|
+
* - Session memory remains in-process (ephemeral Map)
|
|
7
|
+
*/
|
|
8
|
+
export declare class MemoryHarness {
|
|
9
|
+
private session;
|
|
10
|
+
/**
|
|
11
|
+
* Ingest a memory into the Copass backend via `olane ingest text`.
|
|
12
|
+
*/
|
|
13
|
+
remember(key: string, value: string): Promise<{
|
|
14
|
+
success: boolean;
|
|
15
|
+
error?: string;
|
|
16
|
+
}>;
|
|
17
|
+
/**
|
|
18
|
+
* Recall memory via `olane copass question`.
|
|
19
|
+
*/
|
|
20
|
+
recall(query: string): Promise<{
|
|
21
|
+
success: boolean;
|
|
22
|
+
answer?: string;
|
|
23
|
+
error?: string;
|
|
24
|
+
}>;
|
|
25
|
+
/**
|
|
26
|
+
* Search memory via `olane copass context` (fast path search).
|
|
27
|
+
*/
|
|
28
|
+
search(query: string): Promise<{
|
|
29
|
+
success: boolean;
|
|
30
|
+
context?: string;
|
|
31
|
+
error?: string;
|
|
32
|
+
}>;
|
|
33
|
+
sessionSet(key: string, value: unknown): void;
|
|
34
|
+
sessionGet(key: string): unknown | undefined;
|
|
35
|
+
sessionDelete(key: string): boolean;
|
|
36
|
+
sessionClear(): void;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=memory-harness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-harness.d.ts","sourceRoot":"","sources":["../../../src/memory/memory-harness.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAmC;IAElD;;OAEG;IACG,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAYzF;;OAEG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAa3F;;OAEG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAe5F,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAI7C,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAI5C,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAInC,YAAY,IAAI,IAAI;CAGrB"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
/**
|
|
3
|
+
* MemoryHarness — stores and retrieves OS memory via the Copass backend.
|
|
4
|
+
*
|
|
5
|
+
* - `remember(key, value)` → `olane ingest text` with key as entity hint
|
|
6
|
+
* - `recall(query)` → `olane copass question` scoped to memory context
|
|
7
|
+
* - Session memory remains in-process (ephemeral Map)
|
|
8
|
+
*/
|
|
9
|
+
export class MemoryHarness {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.session = new Map();
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Ingest a memory into the Copass backend via `olane ingest text`.
|
|
15
|
+
*/
|
|
16
|
+
async remember(key, value) {
|
|
17
|
+
try {
|
|
18
|
+
await execCli(['ingest', 'text', '--source-type', 'os-memory', '--entity-hints', key, '--additional-context', `OS memory key: ${key}`], `[Memory: ${key}] ${value}`);
|
|
19
|
+
return { success: true };
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
return { success: false, error: String(err) };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Recall memory via `olane copass question`.
|
|
27
|
+
*/
|
|
28
|
+
async recall(query) {
|
|
29
|
+
try {
|
|
30
|
+
const result = await execCli([
|
|
31
|
+
'copass', 'question', query,
|
|
32
|
+
'--detail-level', 'concise',
|
|
33
|
+
'--json',
|
|
34
|
+
]);
|
|
35
|
+
return { success: true, answer: result };
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
return { success: false, error: String(err) };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Search memory via `olane copass context` (fast path search).
|
|
43
|
+
*/
|
|
44
|
+
async search(query) {
|
|
45
|
+
try {
|
|
46
|
+
const result = await execCli([
|
|
47
|
+
'copass', 'context', query,
|
|
48
|
+
'--detail-level', 'concise',
|
|
49
|
+
'--json',
|
|
50
|
+
]);
|
|
51
|
+
return { success: true, context: result };
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
return { success: false, error: String(err) };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// ── Session memory (ephemeral, in-process) ────────────────────
|
|
58
|
+
sessionSet(key, value) {
|
|
59
|
+
this.session.set(key, value);
|
|
60
|
+
}
|
|
61
|
+
sessionGet(key) {
|
|
62
|
+
return this.session.get(key);
|
|
63
|
+
}
|
|
64
|
+
sessionDelete(key) {
|
|
65
|
+
return this.session.delete(key);
|
|
66
|
+
}
|
|
67
|
+
sessionClear() {
|
|
68
|
+
this.session.clear();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function execCli(args, stdin) {
|
|
72
|
+
return new Promise((resolve, reject) => {
|
|
73
|
+
const child = spawn('olane', args, {
|
|
74
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
75
|
+
env: {
|
|
76
|
+
...process.env,
|
|
77
|
+
FORCE_COLOR: '0',
|
|
78
|
+
NODE_OPTIONS: (process.env.NODE_OPTIONS || '')
|
|
79
|
+
.replace(/--inspect[^ ]*/g, '')
|
|
80
|
+
.trim(),
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
let stdout = '';
|
|
84
|
+
let stderr = '';
|
|
85
|
+
child.stdout.on('data', (d) => { stdout += d; });
|
|
86
|
+
child.stderr.on('data', (d) => { stderr += d; });
|
|
87
|
+
child.on('close', (code) => {
|
|
88
|
+
if (code !== 0) {
|
|
89
|
+
reject(new Error(stderr.trim() || `CLI exited with code ${code}`));
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
resolve(stdout.trim());
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
if (stdin !== undefined) {
|
|
96
|
+
child.stdin.write(stdin);
|
|
97
|
+
}
|
|
98
|
+
child.stdin.end();
|
|
99
|
+
});
|
|
100
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { oNodeConfig } from '@olane/o-node';
|
|
2
|
+
import { oLaneTool } from '@olane/o-lane';
|
|
3
|
+
import { oAddress } from '@olane/o-core';
|
|
4
|
+
import type { ToolResult } from '@olane/o-tool';
|
|
5
|
+
import { Libp2pConfig } from '@olane/o-config';
|
|
6
|
+
export interface RelayNodeConfig extends oNodeConfig {
|
|
7
|
+
/** Override relay reservation limits. */
|
|
8
|
+
relay?: {
|
|
9
|
+
maxReservations?: number;
|
|
10
|
+
reservationClearInterval?: number;
|
|
11
|
+
defaultDurationLimit?: number;
|
|
12
|
+
defaultDataLimit?: bigint;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Local relay node — mirrors the private network relay tool
|
|
17
|
+
* (`o-private-network/nodes/relay/src/relay.tool.ts`) but runs
|
|
18
|
+
* on the local oLaneTool base instead of oPrivateNodeTool.
|
|
19
|
+
*
|
|
20
|
+
* Configures libp2p with circuit-relay-v2 server so other nodes
|
|
21
|
+
* can relay connections through this node.
|
|
22
|
+
*/
|
|
23
|
+
export declare class RelayNode extends oLaneTool {
|
|
24
|
+
private relayConfig;
|
|
25
|
+
constructor(config: RelayNodeConfig);
|
|
26
|
+
handleProtocol(address: oAddress): Promise<void>;
|
|
27
|
+
configure(): Promise<Libp2pConfig>;
|
|
28
|
+
initialize(): Promise<void>;
|
|
29
|
+
_tool_identify(): Promise<ToolResult>;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=relay-node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-node.d.ts","sourceRoot":"","sources":["../../../src/nodes/relay-node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAY,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAGL,YAAY,EACb,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD,yCAAyC;IACzC,KAAK,CAAC,EAAE;QACN,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,wBAAwB,CAAC,EAAE,MAAM,CAAC;QAClC,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;CACH;AAED;;;;;;;GAOG;AACH,qBAAa,SAAU,SAAQ,SAAS;IACtC,OAAO,CAAC,WAAW,CAA2B;gBAElC,MAAM,EAAE,eAAe;IAiB7B,cAAc,CAAC,OAAO,EAAE,QAAQ;IAUhC,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC;IAwClC,UAAU;IASV,cAAc,IAAI,OAAO,CAAC,UAAU,CAAC;CAQ5C"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { oLaneTool } from '@olane/o-lane';
|
|
2
|
+
import { oAddress } from '@olane/o-core';
|
|
3
|
+
import { circuitRelayServer } from '@libp2p/circuit-relay-v2';
|
|
4
|
+
import { ping, identify, } from '@olane/o-config';
|
|
5
|
+
/**
|
|
6
|
+
* Local relay node — mirrors the private network relay tool
|
|
7
|
+
* (`o-private-network/nodes/relay/src/relay.tool.ts`) but runs
|
|
8
|
+
* on the local oLaneTool base instead of oPrivateNodeTool.
|
|
9
|
+
*
|
|
10
|
+
* Configures libp2p with circuit-relay-v2 server so other nodes
|
|
11
|
+
* can relay connections through this node.
|
|
12
|
+
*/
|
|
13
|
+
export class RelayNode extends oLaneTool {
|
|
14
|
+
constructor(config) {
|
|
15
|
+
super({
|
|
16
|
+
...config,
|
|
17
|
+
address: config.address || new oAddress('o://relay'),
|
|
18
|
+
description: 'Local relay node for the Olane OS',
|
|
19
|
+
methods: {
|
|
20
|
+
identify: {
|
|
21
|
+
name: 'identify',
|
|
22
|
+
description: 'Get relay identity and transport info',
|
|
23
|
+
parameters: [],
|
|
24
|
+
dependencies: [],
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
this.relayConfig = config.relay;
|
|
29
|
+
}
|
|
30
|
+
async handleProtocol(address) {
|
|
31
|
+
this.logger.debug('Handling protocol with limited connection: ' + address.protocol);
|
|
32
|
+
await this.p2pNode.handle(address.protocol, this.handleStream.bind(this), {
|
|
33
|
+
maxInboundStreams: Infinity,
|
|
34
|
+
maxOutboundStreams: Infinity,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
async configure() {
|
|
38
|
+
const config = await super.configure();
|
|
39
|
+
config.services = {
|
|
40
|
+
identify: identify({
|
|
41
|
+
maxOutboundStreams: Infinity,
|
|
42
|
+
maxInboundStreams: Infinity,
|
|
43
|
+
runOnLimitedConnection: true,
|
|
44
|
+
}),
|
|
45
|
+
ping: ping({
|
|
46
|
+
maxOutboundStreams: Infinity,
|
|
47
|
+
maxInboundStreams: Infinity,
|
|
48
|
+
runOnLimitedConnection: true,
|
|
49
|
+
}),
|
|
50
|
+
relay: circuitRelayServer({
|
|
51
|
+
reservations: {
|
|
52
|
+
maxReservations: this.relayConfig?.maxReservations ?? Infinity,
|
|
53
|
+
reservationClearInterval: this.relayConfig?.reservationClearInterval ?? 60000 * 5,
|
|
54
|
+
defaultDurationLimit: this.relayConfig?.defaultDurationLimit ?? 60000 * 15,
|
|
55
|
+
defaultDataLimit: this.relayConfig?.defaultDataLimit ??
|
|
56
|
+
BigInt(1024 * 1024 * 100000),
|
|
57
|
+
},
|
|
58
|
+
}),
|
|
59
|
+
};
|
|
60
|
+
// Filter out in-memory listeners
|
|
61
|
+
config.listeners = config.listeners?.filter((l) => l.indexOf('/memory/') === -1);
|
|
62
|
+
config.connectionManager = {
|
|
63
|
+
...(config?.connectionManager || {}),
|
|
64
|
+
maxConnections: 500,
|
|
65
|
+
maxParallelDials: 100,
|
|
66
|
+
maxDialQueueLength: 100,
|
|
67
|
+
maxPeerAddrsToDial: 25,
|
|
68
|
+
};
|
|
69
|
+
return config;
|
|
70
|
+
}
|
|
71
|
+
async initialize() {
|
|
72
|
+
await super.initialize();
|
|
73
|
+
this.logger.debug(`Relay node initialized ${this.address.toString()}`);
|
|
74
|
+
this.logger.debug('Multiaddrs:', this.p2pNode.getMultiaddrs());
|
|
75
|
+
this.logger.debug('Protocols:', this.p2pNode.getProtocols());
|
|
76
|
+
}
|
|
77
|
+
async _tool_identify() {
|
|
78
|
+
return {
|
|
79
|
+
success: true,
|
|
80
|
+
address: this.address.toString(),
|
|
81
|
+
staticAddress: this.staticAddress?.toString(),
|
|
82
|
+
transports: this.transports.map((t) => t.toMultiaddr().toString()),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -5,6 +5,12 @@ export interface ApprovalPreferences {
|
|
|
5
5
|
blacklist?: string[];
|
|
6
6
|
timeout?: number;
|
|
7
7
|
}
|
|
8
|
+
export interface OSRelayNodeConfig {
|
|
9
|
+
/** Mark this node as a relay that forwards between local and remote leaders. */
|
|
10
|
+
relay: boolean;
|
|
11
|
+
/** The remote leader address this relay connects to. */
|
|
12
|
+
remoteLeaderAddress?: string;
|
|
13
|
+
}
|
|
8
14
|
export interface OlaneOSConfig {
|
|
9
15
|
configFilePath?: string;
|
|
10
16
|
network?: {
|
|
@@ -16,11 +22,19 @@ export interface OlaneOSConfig {
|
|
|
16
22
|
networkId?: string;
|
|
17
23
|
port?: number;
|
|
18
24
|
};
|
|
19
|
-
nodes?: oNodeConfig[];
|
|
25
|
+
nodes?: (oNodeConfig & Partial<OSRelayNodeConfig>)[];
|
|
20
26
|
lanes?: string[];
|
|
21
27
|
noIndexNetwork?: boolean;
|
|
22
28
|
inProgress?: string[];
|
|
23
29
|
approvalMode?: ApprovalMode;
|
|
24
30
|
approvalPreferences?: ApprovalPreferences;
|
|
31
|
+
/** Copass ID linked to this OS instance. */
|
|
32
|
+
copassId?: string;
|
|
33
|
+
/** World configurations managed by this OS. */
|
|
34
|
+
worlds?: WorldReference[];
|
|
35
|
+
}
|
|
36
|
+
export interface WorldReference {
|
|
37
|
+
id: string;
|
|
38
|
+
name: string;
|
|
25
39
|
}
|
|
26
40
|
//# sourceMappingURL=o-os.config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"o-os.config.d.ts","sourceRoot":"","sources":["../../../../src/o-olane-os/interfaces/o-os.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"o-os.config.d.ts","sourceRoot":"","sources":["../../../../src/o-olane-os/interfaces/o-os.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,gFAAgF;IAChF,KAAK,EAAE,OAAO,CAAC;IACf,wDAAwD;IACxD,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,KAAK,CAAC,EAAE,CAAC,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC;IACrD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd"}
|
|
@@ -4,6 +4,9 @@ import { oLeaderNode } from '@olane/o-leader';
|
|
|
4
4
|
import { oAddress, oObject, oTransport } from '@olane/o-core';
|
|
5
5
|
import { NodeType } from '@olane/o-core';
|
|
6
6
|
import { oLaneTool } from '@olane/o-lane';
|
|
7
|
+
import { WorldManagerTool } from '../worlds/world-manager.tool.js';
|
|
8
|
+
import { AddressBook } from '../address-book/address-book.js';
|
|
9
|
+
import { MemoryHarness } from '../memory/memory-harness.js';
|
|
7
10
|
type OlaneOSNode = oLaneTool | oLeaderNode;
|
|
8
11
|
export declare class OlaneOS extends oObject {
|
|
9
12
|
private leaders;
|
|
@@ -12,6 +15,9 @@ export declare class OlaneOS extends oObject {
|
|
|
12
15
|
status: OlaneOSSystemStatus;
|
|
13
16
|
private config;
|
|
14
17
|
private roundRobinIndex;
|
|
18
|
+
worldManager: WorldManagerTool | null;
|
|
19
|
+
addressBook: AddressBook | null;
|
|
20
|
+
memory: MemoryHarness | null;
|
|
15
21
|
constructor(config: OlaneOSConfig);
|
|
16
22
|
entryNode(): oLaneTool | oLeaderNode;
|
|
17
23
|
addLeader(leader: oLeaderNode): void;
|
|
@@ -25,6 +31,22 @@ export declare class OlaneOS extends oObject {
|
|
|
25
31
|
getOSInstanceName(): Promise<string | undefined>;
|
|
26
32
|
startNodes(type: NodeType): Promise<void>;
|
|
27
33
|
runSavedPlans(): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Initialize world manager, address book, and memory harness
|
|
36
|
+
* after the leader and nodes are started.
|
|
37
|
+
*/
|
|
38
|
+
private initOSServices;
|
|
39
|
+
/**
|
|
40
|
+
* Only index if `indexCompletedAt` is not set in the instance config.
|
|
41
|
+
* Records the timestamp after successful indexing.
|
|
42
|
+
*/
|
|
43
|
+
private indexOnceInBackground;
|
|
44
|
+
/**
|
|
45
|
+
* Index all nodes in the network in parallel.
|
|
46
|
+
* Each node indexes itself + its children concurrently,
|
|
47
|
+
* rather than the default sequential tree walk.
|
|
48
|
+
*/
|
|
49
|
+
private indexNetworkParallel;
|
|
28
50
|
use(oAddress: oAddress, params: any): Promise<import("@olane/o-core").oResponse>;
|
|
29
51
|
start(): Promise<{
|
|
30
52
|
peerId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"o-os.d.ts","sourceRoot":"","sources":["../../../src/o-olane-os/o-os.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"o-os.d.ts","sourceRoot":"","sources":["../../../src/o-olane-os/o-os.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAK5D,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAIzC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAI1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAG5D,KAAK,WAAW,GAAG,SAAS,GAAG,WAAW,CAAC;AAC3C,qBAAa,OAAQ,SAAQ,OAAO;IAClC,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,KAAK,CAAqB;IAC3B,UAAU,EAAE,WAAW,GAAG,IAAI,CAAQ;IACtC,MAAM,EAAG,mBAAmB,CAAC;IACpC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,eAAe,CAAa;IAC7B,YAAY,EAAE,gBAAgB,GAAG,IAAI,CAAQ;IAC7C,WAAW,EAAE,WAAW,GAAG,IAAI,CAAQ;IACvC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAQ;gBAE/B,MAAM,EAAE,aAAa;IAKjC,SAAS,IAAI,SAAS,GAAG,WAAW;IAMpC,SAAS,CAAC,MAAM,EAAE,WAAW;IAOvB,OAAO,CAAC,IAAI,EAAE,WAAW;YAiBjB,UAAU;IA4CxB;;;OAGG;YACW,qBAAqB;IA2E7B,iBAAiB;IASjB,UAAU,CAAC,IAAI,EAAE,QAAQ;IAsDzB,aAAa;IAwEnB;;;OAGG;YACW,cAAc;IAyC5B;;;OAGG;YACW,qBAAqB;IAwBnC;;;;OAIG;YACW,oBAAoB;IA4B5B,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG;IASnC,KAAK,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,UAAU,EAAE,CAAA;KAAE,CAAC;IA0C9D,IAAI;IAwBJ,OAAO;CAKd"}
|