@vxnus/siduri 0.0.6 → 0.0.8

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.
Files changed (39) hide show
  1. package/dist/builtin-manifests.d.ts +2 -0
  2. package/dist/builtin-manifests.js +433 -0
  3. package/dist/clean-machine-e2e.test.js +1 -1
  4. package/dist/configurators/behavior.d.ts +2 -0
  5. package/dist/configurators/behavior.js +36 -0
  6. package/dist/configurators/body.d.ts +2 -0
  7. package/dist/configurators/body.js +44 -0
  8. package/dist/configurators/brain.d.ts +6 -0
  9. package/dist/configurators/brain.js +80 -0
  10. package/dist/configurators/ear.d.ts +2 -0
  11. package/dist/configurators/ear.js +28 -0
  12. package/dist/configurators/hands.d.ts +2 -0
  13. package/dist/configurators/hands.js +27 -0
  14. package/dist/configurators/index.d.ts +23 -0
  15. package/dist/configurators/index.js +74 -0
  16. package/dist/configurators/knowledge.d.ts +6 -0
  17. package/dist/configurators/knowledge.js +100 -0
  18. package/dist/configurators/memory.d.ts +2 -0
  19. package/dist/configurators/memory.js +44 -0
  20. package/dist/configurators/observation.d.ts +2 -0
  21. package/dist/configurators/observation.js +12 -0
  22. package/dist/configurators/types.d.ts +12 -0
  23. package/dist/configurators/types.js +2 -0
  24. package/dist/configurators/vision.d.ts +2 -0
  25. package/dist/configurators/vision.js +39 -0
  26. package/dist/configurators/voice.d.ts +2 -0
  27. package/dist/configurators/voice.js +53 -0
  28. package/dist/configurators.test.d.ts +1 -0
  29. package/dist/configurators.test.js +275 -0
  30. package/dist/discovery.js +8 -0
  31. package/dist/discovery.test.js +7 -0
  32. package/dist/index.d.ts +16 -0
  33. package/dist/index.js +137 -54
  34. package/dist/providers/knowledge-hub.d.ts +37 -0
  35. package/dist/providers/knowledge-hub.js +141 -0
  36. package/dist/providers/openrouter.d.ts +32 -0
  37. package/dist/providers/openrouter.js +201 -0
  38. package/dist/release-check.js +1 -1
  39. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4,6 +4,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  return (mod && mod.__esModule) ? mod : { "default": mod };
5
5
  };
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.colors = exports.CLI_VERSION = void 0;
8
+ exports.printHeader = printHeader;
9
+ exports.printSection = printSection;
10
+ exports.printSuccess = printSuccess;
11
+ exports.projectDirectoryName = projectDirectoryName;
12
+ exports.formatReviewSummary = formatReviewSummary;
13
+ exports.withTask = withTask;
7
14
  exports.runCreateWizard = runCreateWizard;
8
15
  exports.runCliDoctor = runCliDoctor;
9
16
  exports.runCliDb = runCliDb;
@@ -16,24 +23,26 @@ const discovery_1 = require("./discovery");
16
23
  const generator_1 = require("./generator");
17
24
  const doctor_1 = require("./doctor");
18
25
  const db_1 = require("./db");
26
+ const configurators_1 = require("./configurators");
19
27
  const execFile = (0, node_util_1.promisify)(node_child_process_1.execFile);
20
- const CLI_VERSION = '0.0.6';
21
- const colors = {
28
+ exports.CLI_VERSION = '0.0.8';
29
+ exports.colors = {
22
30
  cyan: '\u001b[36m',
23
31
  dim: '\u001b[2m',
24
32
  green: '\u001b[32m',
25
33
  yellow: '\u001b[33m',
34
+ bold: '\u001b[1m',
26
35
  reset: '\u001b[0m',
27
36
  };
28
37
  function printHeader() {
29
- console.log(`\n${colors.cyan}◈ SIDURI${colors.reset} ${colors.dim}companion setup (manifest-driven)${colors.reset}`);
30
- console.log(`${colors.yellow}Version ${CLI_VERSION}${colors.reset} · composable standalone architecture\n`);
38
+ console.log(`\n${exports.colors.cyan}◈ SIDURI${exports.colors.reset} ${exports.colors.dim}companion setup (manifest-driven)${exports.colors.reset}`);
39
+ console.log(`${exports.colors.yellow}Version ${exports.CLI_VERSION}${exports.colors.reset} · composable standalone architecture\n`);
31
40
  }
32
41
  function printSection(title) {
33
- console.log(`\n${colors.cyan}── ${title} ${'─'.repeat(Math.max(2, 42 - title.length))}${colors.reset}`);
42
+ console.log(`\n${exports.colors.cyan}── ${title} ${'─'.repeat(Math.max(2, 42 - title.length))}${exports.colors.reset}\n`);
34
43
  }
35
44
  function printSuccess(message) {
36
- console.log(`${colors.green}✓${colors.reset} ${message}`);
45
+ console.log(`${exports.colors.green}✓${exports.colors.reset} ${message}`);
37
46
  }
38
47
  function projectDirectoryName(value) {
39
48
  const slug = value
@@ -43,22 +52,47 @@ function projectDirectoryName(value) {
43
52
  .replace(/^-+|-+$/g, '');
44
53
  return slug || 'siduri';
45
54
  }
55
+ function formatReviewSummary(companionName, selectedManifests, organSummaries) {
56
+ const lines = [];
57
+ lines.push(`\n${exports.colors.cyan}── Review ${companionName} ${'─'.repeat(Math.max(2, 42 - (companionName.length + 9)))}${exports.colors.reset}\n`);
58
+ lines.push(` ${exports.colors.bold}Companion${exports.colors.reset}`);
59
+ lines.push(` ${exports.colors.dim}Name:${exports.colors.reset} ${companionName}\n`);
60
+ for (const m of selectedManifests) {
61
+ const isRequired = m.organType === 'brain';
62
+ const tag = isRequired ? ` ${exports.colors.dim}· required${exports.colors.reset}` : '';
63
+ lines.push(` ${exports.colors.bold}${m.displayName.split(' ')[0] || m.organType}${exports.colors.reset}${tag}`);
64
+ const summary = organSummaries[m.configKey] || organSummaries[m.organType] || {};
65
+ const entries = Object.entries(summary);
66
+ if (entries.length === 0) {
67
+ lines.push(` ${exports.colors.dim}Provider:${exports.colors.reset} ${m.displayName}`);
68
+ }
69
+ else {
70
+ for (const [key, val] of entries) {
71
+ const valStr = String(val);
72
+ lines.push(` ${exports.colors.dim}${key}:${exports.colors.reset}${' '.repeat(Math.max(1, 10 - key.length))}${valStr}`);
73
+ }
74
+ }
75
+ lines.push('');
76
+ }
77
+ lines.push(`${exports.colors.cyan}${'─'.repeat(46)}${exports.colors.reset}\n`);
78
+ return lines.join('\n');
79
+ }
46
80
  async function withTask(label, task) {
47
- process.stdout.write(`${colors.dim}${label}${colors.reset}`);
81
+ process.stdout.write(`${exports.colors.dim}${label}${exports.colors.reset}`);
48
82
  const frames = ['·', '•', '●', '•'];
49
83
  let index = 0;
50
84
  const timer = setInterval(() => {
51
- process.stdout.write(`\r${colors.dim}${label} ${frames[index++ % frames.length]}${colors.reset}`);
85
+ process.stdout.write(`\r${exports.colors.dim}${label} ${frames[index++ % frames.length]}${exports.colors.reset}`);
52
86
  }, 120);
53
87
  try {
54
88
  const result = await task();
55
89
  clearInterval(timer);
56
- process.stdout.write(`\r${colors.green}✓${colors.reset} ${label}\n`);
90
+ process.stdout.write(`\r${exports.colors.green}✓${exports.colors.reset} ${label}\n`);
57
91
  return result;
58
92
  }
59
93
  catch (error) {
60
94
  clearInterval(timer);
61
- process.stdout.write(`\r${colors.yellow}!${colors.reset} ${label}\n`);
95
+ process.stdout.write(`\r${exports.colors.yellow}!${exports.colors.reset} ${label}\n`);
62
96
  throw error;
63
97
  }
64
98
  }
@@ -86,7 +120,7 @@ async function runCreateWizard(targetDir) {
86
120
  const companionName = basicAnswers.name;
87
121
  const projectDir = targetDir ? node_path_1.default.resolve(process.cwd(), targetDir) : node_path_1.default.resolve(process.cwd(), projectDirectoryName(companionName));
88
122
  printSection('Organ Selection');
89
- console.log(`${colors.dim}Select any combination of organs to compose into your standalone instance.${colors.reset}\n`);
123
+ console.log(`${exports.colors.dim}Select any combination of organs to compose into your standalone instance.${exports.colors.reset}\n`);
90
124
  // Brain is required by architecture contract for cognition
91
125
  const brainManifest = registry.get('brain');
92
126
  const nonBrainManifests = availableManifests.filter((m) => m.organType !== 'brain');
@@ -110,28 +144,77 @@ async function runCreateWizard(targetDir) {
110
144
  if (m)
111
145
  selectedManifests.push(m);
112
146
  }
113
- printSection('Review Composition');
114
- console.log(` ${colors.dim}Companion Name:${colors.reset} ${companionName}`);
115
- console.log(` ${colors.dim}Target Path:${colors.reset} ${projectDir}`);
116
- console.log(` ${colors.dim}Core Protocol:${colors.reset} @siduri-x/core`);
117
- console.log(` ${colors.dim}Selected Organs:${colors.reset}`);
147
+ // 2. Interactive Organ Configuration Stage
148
+ const organConfigs = {};
149
+ const organSummaries = {};
118
150
  for (const m of selectedManifests) {
119
- console.log(` - ${m.displayName} (${colors.dim}${m.name}${colors.reset})`);
151
+ const isRequired = m.organType === 'brain';
152
+ const sectionTitle = isRequired ? `${m.displayName.split(' ')[0] || m.organType} · required` : m.displayName.split(' ')[0] || m.organType;
153
+ printSection(sectionTitle);
154
+ const res = await (0, configurators_1.configureOrgan)(m, {
155
+ companionName,
156
+ existingConfig: organConfigs[m.configKey],
157
+ });
158
+ organConfigs[m.configKey] = res.config;
159
+ organSummaries[m.configKey] = res.summary || {};
120
160
  }
121
- const { confirm } = await inquirer_1.default.prompt({
122
- type: 'confirm',
123
- name: 'confirm',
124
- message: 'Generate standalone Siduri instance with these organs?',
125
- default: true,
126
- });
127
- if (!confirm) {
128
- console.log('Instance creation cancelled.');
129
- return;
161
+ // 3. Final Review and Edit Loop
162
+ while (true) {
163
+ console.log(formatReviewSummary(companionName, selectedManifests, organSummaries));
164
+ const { reviewAction } = await inquirer_1.default.prompt({
165
+ type: 'list',
166
+ name: 'reviewAction',
167
+ message: `Create ${companionName} with this configuration?`,
168
+ choices: [
169
+ { name: 'Yes, create', value: 'create' },
170
+ { name: 'Go back and edit', value: 'edit' },
171
+ { name: 'Cancel', value: 'cancel' },
172
+ ],
173
+ });
174
+ if (reviewAction === 'cancel') {
175
+ console.log('Instance creation cancelled.');
176
+ return;
177
+ }
178
+ if (reviewAction === 'create') {
179
+ break;
180
+ }
181
+ if (reviewAction === 'edit') {
182
+ const editChoices = selectedManifests.map((m) => ({
183
+ name: `Edit ${m.displayName}`,
184
+ value: m.configKey,
185
+ }));
186
+ editChoices.push({ name: 'Edit all organs in sequence', value: '__ALL__' });
187
+ editChoices.push({ name: 'Back to review', value: '__BACK__' });
188
+ const { organToEdit } = await inquirer_1.default.prompt({
189
+ type: 'list',
190
+ name: 'organToEdit',
191
+ message: 'Which organ would you like to edit?',
192
+ choices: editChoices,
193
+ });
194
+ if (organToEdit === '__BACK__') {
195
+ continue;
196
+ }
197
+ const organsToReconfigure = organToEdit === '__ALL__'
198
+ ? selectedManifests
199
+ : selectedManifests.filter((m) => m.configKey === organToEdit);
200
+ for (const m of organsToReconfigure) {
201
+ const isRequired = m.organType === 'brain';
202
+ const sectionTitle = isRequired ? `${m.displayName.split(' ')[0] || m.organType} · required` : m.displayName.split(' ')[0] || m.organType;
203
+ printSection(sectionTitle);
204
+ const res = await (0, configurators_1.configureOrgan)(m, {
205
+ companionName,
206
+ existingConfig: organConfigs[m.configKey],
207
+ });
208
+ organConfigs[m.configKey] = res.config;
209
+ organSummaries[m.configKey] = res.summary || {};
210
+ }
211
+ }
130
212
  }
131
- // 2. Generate Files
213
+ // 4. Generate Instance Files
132
214
  const files = (0, generator_1.generateInstanceFiles)({
133
215
  name: companionName,
134
216
  selectedManifests,
217
+ organConfigs,
135
218
  });
136
219
  await (0, promises_1.mkdir)(projectDir, { recursive: true });
137
220
  await (0, promises_1.mkdir)(node_path_1.default.join(projectDir, 'src'), { recursive: true });
@@ -145,7 +228,7 @@ async function runCreateWizard(targetDir) {
145
228
  await (0, promises_1.mkdir)(node_path_1.default.join(projectDir, 'assets/body/model'), { recursive: true });
146
229
  }
147
230
  printSuccess(`Generated standalone files at ${projectDir}`);
148
- // 3. Install packages if not in dry-run
231
+ // 5. Install packages if not in dry-run
149
232
  try {
150
233
  await withTask('Installing dependencies (npm install)', async () => {
151
234
  await execFile('npm', ['install', '--no-audit', '--no-fund'], { cwd: projectDir });
@@ -153,48 +236,48 @@ async function runCreateWizard(targetDir) {
153
236
  printSuccess('Dependencies installed successfully.');
154
237
  }
155
238
  catch (err) {
156
- console.warn(`${colors.yellow}!${colors.reset} Notice: npm install had warnings or requires network: ${err.message}`);
239
+ console.warn(`${exports.colors.yellow}!${exports.colors.reset} Notice: npm install had warnings or requires network: ${err.message}`);
157
240
  }
158
241
  printSection('Instance Ready');
159
- console.log(`\nYour Siduri companion is ready! Next steps:\n`);
242
+ console.log(`Your Siduri companion is ready! Next steps:\n`);
160
243
  console.log(` cd ${node_path_1.default.relative(process.cwd(), projectDir) || '.'}`);
161
- console.log(` cp .env.example .env ${colors.dim}# Fill in required API keys/credentials${colors.reset}`);
162
- console.log(` npm start ${colors.dim}# Start your standalone companion${colors.reset}\n`);
244
+ console.log(` cp .env.example .env ${exports.colors.dim}# Fill in required API keys/credentials${exports.colors.reset}`);
245
+ console.log(` npm start ${exports.colors.dim}# Start your standalone companion${exports.colors.reset}\n`);
163
246
  }
164
247
  async function runCliDoctor(targetDir) {
165
248
  printHeader();
166
249
  const dir = targetDir ? node_path_1.default.resolve(process.cwd(), targetDir) : process.cwd();
167
- console.log(`${colors.cyan}Siduri Doctor${colors.reset}`);
168
- console.log(`${colors.dim}─────────────${colors.reset}\n`);
250
+ console.log(`${exports.colors.cyan}Siduri Doctor${exports.colors.reset}`);
251
+ console.log(`${exports.colors.dim}─────────────${exports.colors.reset}\n`);
169
252
  try {
170
253
  const report = await (0, doctor_1.runDoctor)({ projectDir: dir });
171
- console.log(`${colors.dim}Instance:${colors.reset} ${report.instanceName}`);
172
- console.log(`${colors.dim}Organs:${colors.reset} ${report.configuredOrgans.join(', ')}\n`);
254
+ console.log(`${exports.colors.dim}Instance:${exports.colors.reset} ${report.instanceName}`);
255
+ console.log(`${exports.colors.dim}Organs:${exports.colors.reset} ${report.configuredOrgans.join(', ')}\n`);
173
256
  const categories = ['Environment', 'Services', 'Database', 'Health Probe'];
174
257
  for (const cat of categories) {
175
258
  const items = report.results.filter((r) => r.category === cat);
176
259
  if (items.length > 0) {
177
- console.log(`${colors.cyan}${cat}${colors.reset}`);
260
+ console.log(`${exports.colors.cyan}${cat}${exports.colors.reset}`);
178
261
  for (const item of items) {
179
262
  if (item.status === 'PASS') {
180
- console.log(` ${colors.green}✓${colors.reset} ${item.name} ${colors.dim}(${item.message || 'OK'})${colors.reset}`);
263
+ console.log(` ${exports.colors.green}✓${exports.colors.reset} ${item.name} ${exports.colors.dim}(${item.message || 'OK'})${exports.colors.reset}`);
181
264
  }
182
265
  else if (item.status === 'OPTIONAL_MISSING') {
183
- console.log(` ${colors.dim}○${colors.reset} ${item.name} ${colors.dim}(Optional, not set)${colors.reset}`);
266
+ console.log(` ${exports.colors.dim}○${exports.colors.reset} ${item.name} ${exports.colors.dim}(Optional, not set)${exports.colors.reset}`);
184
267
  }
185
268
  else if (item.status === 'SKIPPED') {
186
- console.log(` ${colors.dim}— ${item.name} (${item.message})${colors.reset}`);
269
+ console.log(` ${exports.colors.dim}— ${item.name} (${item.message})${exports.colors.reset}`);
187
270
  }
188
271
  else {
189
- console.log(` ${colors.yellow}✗${colors.reset} ${item.name}`);
272
+ console.log(` ${exports.colors.yellow}✗${exports.colors.reset} ${item.name}`);
190
273
  if (item.organName) {
191
- console.log(` ${colors.dim}Required by:${colors.reset} ${item.organName}`);
274
+ console.log(` ${exports.colors.dim}Required by:${exports.colors.reset} ${item.organName}`);
192
275
  }
193
276
  if (item.message) {
194
- console.log(` ${colors.yellow}${item.message}${colors.reset}`);
277
+ console.log(` ${exports.colors.yellow}${item.message}${exports.colors.reset}`);
195
278
  }
196
279
  if (item.remediation) {
197
- console.log(` ${colors.dim}Remediation:${colors.reset} ${item.remediation}`);
280
+ console.log(` ${exports.colors.dim}Remediation:${exports.colors.reset} ${item.remediation}`);
198
281
  }
199
282
  }
200
283
  }
@@ -202,16 +285,16 @@ async function runCliDoctor(targetDir) {
202
285
  }
203
286
  }
204
287
  if (report.passed) {
205
- console.log(`${colors.green}Result: PASS${colors.reset}\n`);
288
+ console.log(`${exports.colors.green}Result: PASS${exports.colors.reset}\n`);
206
289
  process.exitCode = 0;
207
290
  }
208
291
  else {
209
- console.log(`${colors.yellow}Result: FAIL${colors.reset}\n`);
292
+ console.log(`${exports.colors.yellow}Result: FAIL${exports.colors.reset}\n`);
210
293
  process.exitCode = 1;
211
294
  }
212
295
  }
213
296
  catch (err) {
214
- console.error(`\n${colors.yellow}Doctor Error:${colors.reset} ${err.message}\n`);
297
+ console.error(`\n${exports.colors.yellow}Doctor Error:${exports.colors.reset} ${err.message}\n`);
215
298
  process.exitCode = 2;
216
299
  }
217
300
  }
@@ -223,24 +306,24 @@ async function runCliDb(subcommand, targetDir) {
223
306
  return;
224
307
  }
225
308
  const dir = targetDir ? node_path_1.default.resolve(process.cwd(), targetDir) : process.cwd();
226
- console.log(`${colors.cyan}Siduri Database Migrations${colors.reset}`);
227
- console.log(`${colors.dim}──────────────────────────${colors.reset}\n`);
309
+ console.log(`${exports.colors.cyan}Siduri Database Migrations${exports.colors.reset}`);
310
+ console.log(`${exports.colors.dim}──────────────────────────${exports.colors.reset}\n`);
228
311
  try {
229
312
  const res = await (0, db_1.runDbPush)({ projectDir: dir });
230
313
  if (res.status === 'NOOP') {
231
- console.log(`${colors.dim}— ${res.message}${colors.reset}\n`);
314
+ console.log(`${exports.colors.dim}— ${res.message}${exports.colors.reset}\n`);
232
315
  }
233
316
  else {
234
317
  printSuccess(res.message);
235
318
  if (res.appliedMigrations.length > 0) {
236
- console.log(`${colors.dim}Applied:${colors.reset} ${res.appliedMigrations.join(', ')}`);
319
+ console.log(`${exports.colors.dim}Applied:${exports.colors.reset} ${res.appliedMigrations.join(', ')}`);
237
320
  }
238
321
  console.log();
239
322
  }
240
323
  process.exitCode = 0;
241
324
  }
242
325
  catch (err) {
243
- console.error(`\n${colors.yellow}Database Migration Error:${colors.reset} ${err.message}\n`);
326
+ console.error(`\n${exports.colors.yellow}Database Migration Error:${exports.colors.reset} ${err.message}\n`);
244
327
  process.exitCode = 3;
245
328
  }
246
329
  }
@@ -248,7 +331,7 @@ async function main() {
248
331
  const args = process.argv.slice(2);
249
332
  const command = args[0];
250
333
  if (command === '--version' || command === '-v') {
251
- console.log(CLI_VERSION);
334
+ console.log(exports.CLI_VERSION);
252
335
  return;
253
336
  }
254
337
  if (command === 'create') {
@@ -279,7 +362,7 @@ if (require.main === module) {
279
362
  console.log('\nOperation cancelled.');
280
363
  return;
281
364
  }
282
- console.error(`\n${colors.yellow}!${colors.reset} ${error instanceof Error ? error.message : error}`);
365
+ console.error(`\n${exports.colors.yellow}!${exports.colors.reset} ${error instanceof Error ? error.message : error}`);
283
366
  process.exitCode = 1;
284
367
  });
285
368
  }
@@ -0,0 +1,37 @@
1
+ export interface KnowledgeHubCapabilities {
2
+ search?: boolean;
3
+ retrieval?: boolean;
4
+ contextInjection?: boolean;
5
+ semanticSearch?: boolean;
6
+ lexicalSearch?: boolean;
7
+ [key: string]: unknown;
8
+ }
9
+ export interface KnowledgeHubManifest {
10
+ name: string;
11
+ displayName?: string;
12
+ publisher?: string;
13
+ package?: string;
14
+ version: string;
15
+ description?: string;
16
+ capabilities?: KnowledgeHubCapabilities | string[];
17
+ distribution?: {
18
+ kind?: string;
19
+ url?: string;
20
+ };
21
+ source?: string;
22
+ environment?: Array<{
23
+ name: string;
24
+ required?: boolean;
25
+ description?: string;
26
+ }>;
27
+ }
28
+ export declare const KNOWN_KNOWLEDGE_PACKS: Record<string, KnowledgeHubManifest>;
29
+ export declare function validateKnowledgeManifest(raw: unknown, packId?: string): KnowledgeHubManifest;
30
+ export declare function extractCapabilitiesList(capabilities?: KnowledgeHubCapabilities | string[]): string[];
31
+ export declare class KnowledgeHubClient {
32
+ private registryUrl;
33
+ private timeoutMs;
34
+ constructor(registryUrl?: string, timeoutMs?: number);
35
+ resolveProvider(packId: string): Promise<KnowledgeHubManifest>;
36
+ }
37
+ export declare function displayKnowledgeProviderSummary(manifest: KnowledgeHubManifest, packId: string): void;
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KnowledgeHubClient = exports.KNOWN_KNOWLEDGE_PACKS = void 0;
4
+ exports.validateKnowledgeManifest = validateKnowledgeManifest;
5
+ exports.extractCapabilitiesList = extractCapabilitiesList;
6
+ exports.displayKnowledgeProviderSummary = displayKnowledgeProviderSummary;
7
+ exports.KNOWN_KNOWLEDGE_PACKS = {
8
+ '@vxnus/e-teyvat': {
9
+ name: 'e-teyvat',
10
+ displayName: 'E Teyvat',
11
+ publisher: 'vxnus',
12
+ package: '@vxnus/e-teyvat',
13
+ version: '1.2.0',
14
+ description: 'Teyvat knowledge provider for Siduri.',
15
+ capabilities: ['Search', 'Retrieval', 'Context injection'],
16
+ distribution: {
17
+ kind: 'provider',
18
+ url: 'https://teyvat.e.vxnus.xyz',
19
+ },
20
+ source: 'E Knowledge Hub',
21
+ },
22
+ };
23
+ function validateKnowledgeManifest(raw, packId) {
24
+ if (!raw || typeof raw !== 'object') {
25
+ throw new Error(`Invalid knowledge manifest: expected object.`);
26
+ }
27
+ const m = raw;
28
+ if (!m.name || typeof m.name !== 'string') {
29
+ throw new Error(`Invalid knowledge manifest: missing 'name' field.`);
30
+ }
31
+ if (!m.version || typeof m.version !== 'string') {
32
+ throw new Error(`Invalid knowledge manifest: missing 'version' field.`);
33
+ }
34
+ return {
35
+ name: m.name,
36
+ displayName: m.displayName || m.name,
37
+ publisher: m.publisher,
38
+ package: m.package || packId || m.name,
39
+ version: m.version,
40
+ description: m.description || 'Knowledge pack provider',
41
+ capabilities: m.capabilities || ['Search', 'Retrieval'],
42
+ distribution: m.distribution,
43
+ source: m.source || 'E Knowledge Hub',
44
+ environment: m.environment || [],
45
+ };
46
+ }
47
+ function extractCapabilitiesList(capabilities) {
48
+ if (!capabilities) {
49
+ return ['Search', 'Retrieval'];
50
+ }
51
+ if (Array.isArray(capabilities)) {
52
+ return capabilities.map((c) => String(c));
53
+ }
54
+ const result = [];
55
+ if (capabilities.lexicalSearch || capabilities.search)
56
+ result.push('Search');
57
+ result.push('Retrieval');
58
+ if (capabilities.contextInjection)
59
+ result.push('Context injection');
60
+ if (capabilities.semanticSearch)
61
+ result.push('Semantic search');
62
+ if (capabilities.structuredEntities)
63
+ result.push('Structured entities');
64
+ if (capabilities.relations)
65
+ result.push('Entity relations');
66
+ if (capabilities.revisions)
67
+ result.push('Content revisions');
68
+ for (const [key, val] of Object.entries(capabilities)) {
69
+ if (val === true && !['search', 'retrieval', 'contextInjection', 'semanticSearch', 'lexicalSearch', 'structuredEntities', 'relations', 'revisions'].includes(key)) {
70
+ result.push(key);
71
+ }
72
+ }
73
+ return result.length > 0 ? result : ['Search', 'Retrieval'];
74
+ }
75
+ class KnowledgeHubClient {
76
+ registryUrl;
77
+ timeoutMs;
78
+ constructor(registryUrl = 'https://e.vxnus.xyz/api/v1/knowledge', timeoutMs = 5000) {
79
+ this.registryUrl = registryUrl.replace(/\/+$/, '');
80
+ this.timeoutMs = timeoutMs;
81
+ }
82
+ async resolveProvider(packId) {
83
+ const trimmed = packId.trim();
84
+ const match = trimmed.match(/^@([^/]+)\/([^/]+)$/);
85
+ if (!match) {
86
+ throw new Error(`Invalid package ID format "${packId}". Expected format: @publisher/name (e.g. @vxnus/e-teyvat)`);
87
+ }
88
+ const publisher = match[1];
89
+ const name = match[2];
90
+ const url = `${this.registryUrl}/${encodeURIComponent(publisher)}/${encodeURIComponent(name)}`;
91
+ const controller = new AbortController();
92
+ const timer = setTimeout(() => controller.abort(), this.timeoutMs);
93
+ try {
94
+ const response = await fetch(url, {
95
+ method: 'GET',
96
+ headers: { Accept: 'application/json' },
97
+ signal: controller.signal,
98
+ });
99
+ if (!response.ok) {
100
+ // Check offline/built-in catalog fallback for known pack IDs
101
+ if (exports.KNOWN_KNOWLEDGE_PACKS[trimmed]) {
102
+ return exports.KNOWN_KNOWLEDGE_PACKS[trimmed];
103
+ }
104
+ throw new Error(`HTTP ${response.status}: ${response.statusText} for ${packId}`);
105
+ }
106
+ const body = await response.json();
107
+ return validateKnowledgeManifest(body, trimmed);
108
+ }
109
+ catch (err) {
110
+ // If network fails and known pack exists, use fallback
111
+ if (exports.KNOWN_KNOWLEDGE_PACKS[trimmed]) {
112
+ return exports.KNOWN_KNOWLEDGE_PACKS[trimmed];
113
+ }
114
+ throw new Error(`Failed to resolve package "${packId}" from E Knowledge Hub: ${err.message}`);
115
+ }
116
+ finally {
117
+ clearTimeout(timer);
118
+ }
119
+ }
120
+ }
121
+ exports.KnowledgeHubClient = KnowledgeHubClient;
122
+ function displayKnowledgeProviderSummary(manifest, packId) {
123
+ const cyan = '\u001b[36m';
124
+ const dim = '\u001b[2m';
125
+ const reset = '\u001b[0m';
126
+ console.log(`\n${cyan}── Knowledge Provider ────────────────────────${reset}\n`);
127
+ console.log(` ${dim}Name:${reset} ${manifest.displayName || manifest.name}`);
128
+ console.log(` ${dim}Package:${reset} ${packId}`);
129
+ console.log(` ${dim}Version:${reset} ${manifest.version}`);
130
+ if (manifest.description) {
131
+ console.log(`\n ${dim}Description:${reset}`);
132
+ console.log(` ${manifest.description}`);
133
+ }
134
+ const caps = extractCapabilitiesList(manifest.capabilities);
135
+ console.log(`\n ${dim}Capabilities:${reset}`);
136
+ for (const cap of caps) {
137
+ console.log(` • ${cap}`);
138
+ }
139
+ console.log(`\n ${dim}Source:${reset}`);
140
+ console.log(` ${manifest.source || 'E Knowledge Hub'}\n`);
141
+ }
@@ -0,0 +1,32 @@
1
+ export interface ModelOption {
2
+ id: string;
3
+ name: string;
4
+ description?: string;
5
+ contextLength?: number;
6
+ }
7
+ export interface ModelProvider {
8
+ listModels(): Promise<ModelOption[]>;
9
+ }
10
+ export declare const CURATED_OPENROUTER_MODELS: ModelOption[];
11
+ export declare class OpenRouterModelProvider implements ModelProvider {
12
+ private apiUrl;
13
+ private timeoutMs;
14
+ constructor(apiUrl?: string, timeoutMs?: number);
15
+ listModels(): Promise<ModelOption[]>;
16
+ }
17
+ export type ModelSelectionResult = {
18
+ type: 'selected';
19
+ modelId: string;
20
+ modelName: string;
21
+ } | {
22
+ type: 'manual';
23
+ modelId: string;
24
+ } | {
25
+ type: 'switch_provider';
26
+ } | {
27
+ type: 'cancel';
28
+ };
29
+ /**
30
+ * Interactive model selector with search, pagination, and robust error recovery.
31
+ */
32
+ export declare function promptOpenRouterModelSelection(provider?: ModelProvider): Promise<ModelSelectionResult>;