UNPKG

newo

Version:

NEWO CLI: Professional command-line tool with modular architecture for NEWO AI Agent development. Features account migration, integration management, webhook automation, AKB knowledge base, project attributes, sandbox testing, IDN-based file management, r

175 lines • 6.93 kB
/** * AKB (Knowledge Base) synchronization module * Handles pull/push of AKB articles for personas with agents */ import path from 'path'; import fs from 'fs-extra'; import yaml from 'js-yaml'; import { searchPersonas, getAkbTopics, importAkbArticle } from '../api.js'; /** * Pull AKB articles for all personas linked to agents */ export async function pullAkb(client, customerDir, verbose = false) { if (verbose) console.log('\nšŸ“š Pulling AKB (Knowledge Base) from NEWO platform...\n'); // Create AKB directory const akbDir = path.join(customerDir, 'akb'); await fs.ensureDir(akbDir); // Fetch personas linked to agents let allPersonas = []; let page = 1; const perPage = 30; while (true) { const response = await searchPersonas(client, true, page, perPage); allPersonas = allPersonas.concat(response.items); if (verbose) console.log(`āœ“ Fetched ${response.items.length} personas (page ${page}/${Math.ceil(response.metadata.total / perPage)})`); if (response.items.length < perPage || allPersonas.length >= response.metadata.total) { break; } page++; } if (verbose) console.log(`\nāœ“ Found ${allPersonas.length} personas linked to agents`); let totalArticles = 0; // Fetch AKB articles for each persona for (const persona of allPersonas) { if (verbose) console.log(`\n šŸ“– Processing persona: ${persona.name} (${persona.agent.idn})`); // Fetch all AKB topics for this persona let allTopicItems = []; let topicPage = 1; const topicsPerPage = 100; while (true) { try { const topicsResponse = await getAkbTopics(client, persona.id, topicPage, topicsPerPage); allTopicItems = allTopicItems.concat(topicsResponse.items); if (verbose) console.log(` āœ“ Fetched ${topicsResponse.items.length} topics (page ${topicPage})`); if (topicsResponse.items.length < topicsPerPage || allTopicItems.length >= topicsResponse.metadata.total) { break; } topicPage++; } catch (error) { if (verbose) console.log(` ⚠ Could not fetch topics: ${error.message}`); break; } } if (allTopicItems.length > 0) { // Convert to YAML format (extract topic from each item) const yamlTopics = allTopicItems.map(item => ({ topic_name: item.topic.topic_name, topic_facts: [...item.topic.topic_facts], confidence: item.topic.confidence, source: item.topic.source, created_at: item.topic.created_at, updated_at: item.topic.updated_at, labels: [...item.topic.labels], topic_summary: item.topic.topic_summary })); // Save to persona-specific YAML file using agent IDN const agentIdn = persona.agent.idn; const akbFile = path.join(akbDir, `${agentIdn}.yaml`); await fs.writeFile(akbFile, yaml.dump(yamlTopics, { lineWidth: -1 })); if (verbose) console.log(` āœ“ Saved ${allTopicItems.length} articles → ${agentIdn}.yaml`); totalArticles += allTopicItems.length; } else { if (verbose) console.log(` ℹ No AKB articles found for this persona`); } } if (verbose) { console.log(`\nāœ… Saved AKB articles for ${allPersonas.length} personas`); console.log(` Total articles: ${totalArticles}\n`); } } /** * Push AKB articles from local files to NEWO platform */ export async function pushAkb(client, customerDir, verbose = false) { if (verbose) console.log('\nšŸ“¤ Pushing AKB articles to NEWO platform...\n'); const akbDir = path.join(customerDir, 'akb'); // Check if AKB directory exists if (!await fs.pathExists(akbDir)) { if (verbose) console.log('⚠ No akb directory found. Run pull-akb first.'); return; } // Get personas linked to agents for ID mapping let allPersonas = []; let page = 1; const perPage = 30; while (true) { const response = await searchPersonas(client, true, page, perPage); allPersonas = allPersonas.concat(response.items); if (response.items.length < perPage || allPersonas.length >= response.metadata.total) { break; } page++; } // Create persona mapping (agent.idn -> persona.id) const personaMap = new Map(); allPersonas.forEach(persona => { personaMap.set(persona.agent.idn, persona.id); personaMap.set(persona.name, persona.id); // Also map by name as fallback }); // Read AKB files const akbFiles = await fs.readdir(akbDir); let totalImported = 0; let totalFailed = 0; for (const file of akbFiles) { if (!file.endsWith('.yaml')) continue; const fileBase = file.replace('.yaml', ''); const personaId = personaMap.get(fileBase); if (!personaId) { if (verbose) console.log(`⚠ Persona not found for file: ${file}, skipping...`); continue; } if (verbose) console.log(`\n šŸ“– Processing: ${file}`); // Read YAML file const akbFile = path.join(akbDir, file); const topics = yaml.load(await fs.readFile(akbFile, 'utf-8')); if (!Array.isArray(topics)) { if (verbose) console.log(` ⚠ Invalid YAML format, skipping...`); continue; } // Import each article for (const topic of topics) { try { const articleData = { topic_name: topic.topic_name, topic_summary: topic.topic_summary, topic_facts: topic.topic_facts, confidence: topic.confidence, source: topic.source, labels: topic.labels, persona_id: personaId }; await importAkbArticle(client, articleData); totalImported++; if (verbose) console.log(` āœ“ Imported: ${topic.topic_name}`); } catch (error) { totalFailed++; if (verbose) console.error(` āŒ Failed to import ${topic.topic_name}: ${error.message}`); } } } if (verbose) { console.log(`\nāœ… Push completed:`); console.log(` Imported: ${totalImported}`); console.log(` Failed: ${totalFailed}\n`); } } //# sourceMappingURL=akb.js.map