@vxnus/siduri 0.0.2 → 0.0.4
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 +8 -3
- package/dist/index.js +46 -26
- package/dist/runtime.js +2486 -710
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -5,11 +5,12 @@ Experimental CLI for creating and configuring Siduri companions.
|
|
|
5
5
|
Requires Node.js 20 or newer.
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npx @vxnus/siduri@0.0.
|
|
8
|
+
npx @vxnus/siduri@0.0.4 create
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
The companion name becomes the project directory. For example, answering
|
|
12
|
-
`
|
|
12
|
+
`My Companion` creates `./my-companion/siduri.config.json` from the current
|
|
13
|
+
directory.
|
|
13
14
|
|
|
14
15
|
The wizard configures the required Brain and Memory organs, then lets you
|
|
15
16
|
enable or disable Voice, Knowledge, Behavior, Body, and Vision. Knowledge can
|
|
@@ -21,6 +22,10 @@ Brain providers:
|
|
|
21
22
|
- **OpenAI-compatible API** — a custom `baseUrl`, model ID, and API-key
|
|
22
23
|
environment variable.
|
|
23
24
|
|
|
25
|
+
Memory currently uses PostgreSQL. The wizard lets you choose Local PostgreSQL,
|
|
26
|
+
Neon, Supabase, or another PostgreSQL provider; all use `DATABASE_URL`. SQLite
|
|
27
|
+
is shown as a future option but is not selectable in this release.
|
|
28
|
+
|
|
24
29
|
The wizard creates a project directory from the companion name, writes
|
|
25
30
|
`siduri.config.json`, copies the Siduri runtime, and installs the runtime
|
|
26
31
|
dependencies. API keys are never written to the configuration file. Optional
|
|
@@ -30,7 +35,7 @@ required.
|
|
|
30
35
|
After setup, start the generated instance with:
|
|
31
36
|
|
|
32
37
|
```bash
|
|
33
|
-
cd
|
|
38
|
+
cd my-companion
|
|
34
39
|
npm run start
|
|
35
40
|
```
|
|
36
41
|
|
package/dist/index.js
CHANGED
|
@@ -13,11 +13,11 @@ const node_util_1 = require("node:util");
|
|
|
13
13
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
14
14
|
const e_knowledge_1 = require("@vxnus/e-knowledge");
|
|
15
15
|
const execFile = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
16
|
-
const DEFAULT_REGISTRY_URL = 'https://e.vxnus.xyz/api/
|
|
17
|
-
const CLI_VERSION = '0.0.
|
|
16
|
+
const DEFAULT_REGISTRY_URL = 'https://e.vxnus.xyz/api/v1/knowledge';
|
|
17
|
+
const CLI_VERSION = '0.0.4';
|
|
18
18
|
const RUNTIME_DEPENDENCIES = {
|
|
19
|
-
'@vxnus/e': '^0.1.
|
|
20
|
-
'@vxnus/e-knowledge': '^0.1.
|
|
19
|
+
'@vxnus/e': '^0.1.4',
|
|
20
|
+
'@vxnus/e-knowledge': '^0.1.4',
|
|
21
21
|
cors: '^2.8.5',
|
|
22
22
|
express: '^4.18.2',
|
|
23
23
|
pg: '^8.23.0',
|
|
@@ -33,7 +33,7 @@ const colors = {
|
|
|
33
33
|
};
|
|
34
34
|
function printHeader() {
|
|
35
35
|
console.log(`\n${colors.cyan}◈ SIDURI${colors.reset} ${colors.dim}companion setup${colors.reset}`);
|
|
36
|
-
console.log(`${colors.yellow}Experimental release 0.0.
|
|
36
|
+
console.log(`${colors.yellow}Experimental release 0.0.4${colors.reset} · configuration may change\n`);
|
|
37
37
|
}
|
|
38
38
|
function printSection(title) {
|
|
39
39
|
console.log(`\n${colors.cyan}── ${title} ${'─'.repeat(Math.max(2, 42 - title.length))}${colors.reset}`);
|
|
@@ -185,13 +185,13 @@ async function chooseHubPack(registryUrl) {
|
|
|
185
185
|
const { query } = await inquirer_1.default.prompt({
|
|
186
186
|
type: 'input',
|
|
187
187
|
name: 'query',
|
|
188
|
-
message: 'Search
|
|
188
|
+
message: 'Search E Knowledge Hub or enter package ID (e.g. @vxnus/e-teyvat):',
|
|
189
189
|
});
|
|
190
190
|
const normalized = query.trim().replace(/^@/, '');
|
|
191
191
|
const [publisher, name] = normalized.split('/');
|
|
192
192
|
const result = publisher && name && !query.includes(' ')
|
|
193
|
-
? await withTask('Searching Knowledge Hub', () => getJson(`${registryUrl}/${encodeURIComponent(publisher)}/${encodeURIComponent(name)}`))
|
|
194
|
-
: await withTask('Searching Knowledge Hub', () => getJson(`${registryUrl}?q=${encodeURIComponent(query)}&limit=20`));
|
|
193
|
+
? await withTask('Searching E Knowledge Hub', () => getJson(`${registryUrl}/${encodeURIComponent(publisher)}/${encodeURIComponent(name)}`))
|
|
194
|
+
: await withTask('Searching E Knowledge Hub', () => getJson(`${registryUrl}?q=${encodeURIComponent(query)}&limit=20`));
|
|
195
195
|
const packs = 'packs' in result ? result.packs : [result];
|
|
196
196
|
if (packs.length === 0)
|
|
197
197
|
throw new Error(`No knowledge packs found for '${query}'`);
|
|
@@ -211,7 +211,7 @@ async function configureKnowledge() {
|
|
|
211
211
|
name: 'mode',
|
|
212
212
|
message: 'Knowledge source?',
|
|
213
213
|
choices: [
|
|
214
|
-
{ name: 'Knowledge Hub', value: 'hub' },
|
|
214
|
+
{ name: 'E Knowledge Hub', value: 'hub' },
|
|
215
215
|
{ name: 'Installed local pack', value: 'local' },
|
|
216
216
|
{ name: 'Hosted provider URL', value: 'remote' },
|
|
217
217
|
{ name: 'Do not use knowledge', value: 'none' },
|
|
@@ -238,18 +238,16 @@ async function configureKnowledge() {
|
|
|
238
238
|
message: 'Remote knowledge provider URL:',
|
|
239
239
|
});
|
|
240
240
|
const provider = (0, e_knowledge_1.createRemoteProvider)({ baseUrl, timeoutMs: 5000 });
|
|
241
|
-
const manifest = await withTask('Checking provider manifest', async () =>
|
|
241
|
+
const manifest = await withTask('Checking provider manifest', async () => {
|
|
242
|
+
if (!provider.manifest) {
|
|
243
|
+
throw new Error('Remote knowledge provider does not support manifest inspection');
|
|
244
|
+
}
|
|
245
|
+
return provider.manifest();
|
|
246
|
+
});
|
|
242
247
|
printSuccess(`Provider ready · ${manifest.id}`);
|
|
243
248
|
return { provider: 'e-remote', baseUrl: baseUrl.replace(/\/+$/, ''), timeoutMs: 5000 };
|
|
244
249
|
}
|
|
245
|
-
const
|
|
246
|
-
type: 'input',
|
|
247
|
-
name: 'registryUrl',
|
|
248
|
-
message: 'Knowledge Hub registry URL:',
|
|
249
|
-
default: process.env.SIDURI_KNOWLEDGE_REGISTRY_URL || DEFAULT_REGISTRY_URL,
|
|
250
|
-
validate: urlValue,
|
|
251
|
-
});
|
|
252
|
-
const registryUrl = enteredRegistryUrl.replace(/\/+$/, '');
|
|
250
|
+
const registryUrl = (process.env.E_REGISTRY_URL || process.env.SIDURI_KNOWLEDGE_REGISTRY_URL || DEFAULT_REGISTRY_URL).replace(/\/+$/, '');
|
|
253
251
|
const pack = await chooseHubPack(registryUrl);
|
|
254
252
|
if (pack.distribution.kind === 'archive') {
|
|
255
253
|
const { install } = await inquirer_1.default.prompt({
|
|
@@ -269,7 +267,12 @@ async function configureKnowledge() {
|
|
|
269
267
|
throw new Error('Archive installation was declined and no hosted provider is available');
|
|
270
268
|
}
|
|
271
269
|
const provider = (0, e_knowledge_1.createRemoteProvider)({ baseUrl: pack.distribution.url, timeoutMs: 5000 });
|
|
272
|
-
await withTask('Checking provider manifest', async () =>
|
|
270
|
+
await withTask('Checking provider manifest', async () => {
|
|
271
|
+
if (!provider.manifest) {
|
|
272
|
+
throw new Error('Remote knowledge provider does not support manifest inspection');
|
|
273
|
+
}
|
|
274
|
+
return provider.manifest();
|
|
275
|
+
});
|
|
273
276
|
printSuccess(`Provider ready · ${pack.id}`);
|
|
274
277
|
return { provider: 'e-hub', registryUrl, packId: pack.id, timeoutMs: 5000 };
|
|
275
278
|
}
|
|
@@ -294,11 +297,30 @@ async function main() {
|
|
|
294
297
|
printSection('Companion');
|
|
295
298
|
const answers = await inquirer_1.default.prompt([
|
|
296
299
|
{ type: 'input', name: 'name', message: 'Companion name:', default: 'Siduri', validate: nonEmpty },
|
|
297
|
-
{
|
|
300
|
+
{
|
|
301
|
+
type: 'list',
|
|
302
|
+
name: 'memoryEngine',
|
|
303
|
+
message: 'Memory database?',
|
|
304
|
+
choices: [
|
|
305
|
+
{ name: 'PostgreSQL', value: 'postgres' },
|
|
306
|
+
{ name: 'SQLite (future)', value: 'sqlite', disabled: 'Coming soon' },
|
|
307
|
+
],
|
|
308
|
+
},
|
|
298
309
|
]);
|
|
310
|
+
const { memoryDeployment } = await inquirer_1.default.prompt({
|
|
311
|
+
type: 'list',
|
|
312
|
+
name: 'memoryDeployment',
|
|
313
|
+
message: 'PostgreSQL deployment?',
|
|
314
|
+
choices: [
|
|
315
|
+
{ name: 'Local PostgreSQL', value: 'local' },
|
|
316
|
+
{ name: 'Neon', value: 'neon' },
|
|
317
|
+
{ name: 'Supabase', value: 'supabase' },
|
|
318
|
+
{ name: 'Other PostgreSQL provider', value: 'other' },
|
|
319
|
+
],
|
|
320
|
+
});
|
|
299
321
|
const projectPath = node_path_1.default.resolve(process.cwd(), projectDirectoryName(answers.name));
|
|
300
322
|
await (0, promises_1.mkdir)(projectPath, { recursive: true });
|
|
301
|
-
printSuccess(`${answers.name} · PostgreSQL
|
|
323
|
+
printSuccess(`${answers.name} · PostgreSQL / ${memoryDeployment} · ${projectPath}`);
|
|
302
324
|
printSection('Brain · required');
|
|
303
325
|
const { brainProvider } = await inquirer_1.default.prompt({
|
|
304
326
|
type: 'list',
|
|
@@ -337,7 +359,7 @@ async function main() {
|
|
|
337
359
|
const knowledge = await configureKnowledge();
|
|
338
360
|
const remaining = await inquirer_1.default.prompt([
|
|
339
361
|
{ type: 'list', name: 'behavior', message: 'Behavior preset?', choices: [{ name: 'Calm', value: 'Calm' }, { name: 'Cheerful, Encouraging', value: 'Cheerful, Encouraging' }, { name: 'Do not use custom behavior', value: 'none' }] },
|
|
340
|
-
{ type: 'list', name: 'body', message: 'Body provider?', choices: [{ name: '
|
|
362
|
+
{ type: 'list', name: 'body', message: 'Body provider?', choices: [{ name: 'Live2D Body (Renderer-agnostic)', value: 'live2d' }, { name: 'Do not use body', value: 'none' }] },
|
|
341
363
|
{ type: 'list', name: 'vision', message: 'Vision provider?', choices: [{ name: 'OpenRouter vision', value: 'openrouter' }, { name: 'Do not use vision', value: 'none' }] },
|
|
342
364
|
]);
|
|
343
365
|
const config = {
|
|
@@ -345,10 +367,10 @@ async function main() {
|
|
|
345
367
|
name: answers.name,
|
|
346
368
|
brain,
|
|
347
369
|
voice: { provider: voice, speakerId: 1 },
|
|
348
|
-
memory: { provider: answers.
|
|
370
|
+
memory: { provider: answers.memoryEngine, deployment: memoryDeployment },
|
|
349
371
|
knowledge,
|
|
350
372
|
behavior: { provider: remaining.behavior === 'none' ? 'none' : 'active_self', preset: remaining.behavior },
|
|
351
|
-
body: { provider: remaining.body
|
|
373
|
+
body: { provider: remaining.body },
|
|
352
374
|
vision: { provider: remaining.vision, model: 'gpt-4-vision' },
|
|
353
375
|
};
|
|
354
376
|
const configPath = node_path_1.default.join(projectPath, 'siduri.config.json');
|
|
@@ -401,8 +423,6 @@ async function main() {
|
|
|
401
423
|
await (0, promises_1.writeFile)(node_path_1.default.join(projectPath, '.env.example'), [
|
|
402
424
|
`${keyEnv}=`,
|
|
403
425
|
'DATABASE_URL=postgresql://postgres:postgres@localhost:5432/siduri',
|
|
404
|
-
'VTS_URL=ws://127.0.0.1:8001',
|
|
405
|
-
'VTS_AUTH_TOKEN=',
|
|
406
426
|
'',
|
|
407
427
|
].join('\n'), { mode: 0o600 });
|
|
408
428
|
await withTask('Installing Siduri runtime dependencies', () => execFile('npm', ['install', '--no-audit', '--no-fund'], { cwd: projectPath }).then(() => undefined));
|