Files
zalbot/scripts/search-lore.ts
Kaysser Kayyali b884a13d98
Some checks failed
tests / Unit tests (Node 22) (push) Failing after 28s
fix wizard for new stories
2026-06-20 06:52:19 +00:00

65 lines
2.5 KiB
TypeScript

// Read-only GraphMCP lore lookup for encounter authoring. Lets the
// mardonar-encounter skill ground NPCs/setting in existing canon without writing
// to the knowledge graph. Uses the engine's own src/graphmcp/client.js (which
// already normalizes null / non-array GraphMCP responses).
//
// Requires GRAPHMCP_URL reachable from the host (default http://localhost:9000).
// If GraphMCP is unreachable, the fetch will throw — the skill surfaces that to
// the user as "GraphMCP unreachable — authoring without canon grounding."
//
// Usage (run from the engine repo root):
// npx tsx scripts/search-lore.ts search "<query>" [limit] # semantic_search
// npx tsx scripts/search-lore.ts npc "<name>" "<question>" [limit] # query_as_npc
//
// Exit 0 with results (or "no matches"); exit 1 on fetch/parse failure; exit 2 on usage error.
import { semanticSearch, queryAsNPC, formatNPCMemory } from '../src/graphmcp/client.js';
const mode = process.argv[2];
async function main(): Promise<void> {
if (mode === 'search') {
const query = process.argv[3];
const limit = Number(process.argv[4] ?? 5);
if (!query) {
console.error('Usage: npx tsx scripts/search-lore.ts search "<query>" [limit]');
process.exit(2);
}
try {
const r = await semanticSearch(query, limit);
if (r.chunks.length === 0) {
console.log('No lore chunks matched.');
return;
}
for (const c of r.chunks) {
const snippet = c.content.length > 300 ? c.content.slice(0, 297) + '…' : c.content;
console.log(`[${c.score.toFixed(3)}] ${c.source ?? '?'}: ${snippet}`);
}
} catch (err) {
console.error(`GraphMCP search failed: ${String((err as Error)?.message ?? err)}`);
process.exit(1);
}
} else if (mode === 'npc') {
const name = process.argv[3];
const question = process.argv[4];
const limit = Number(process.argv[5] ?? 5);
if (!name || !question) {
console.error('Usage: npx tsx scripts/search-lore.ts npc "<name>" "<question>" [limit]');
process.exit(2);
}
try {
const r = await queryAsNPC(name, question, limit);
console.log(formatNPCMemory(r));
} catch (err) {
console.error(`GraphMCP npc query failed: ${String((err as Error)?.message ?? err)}`);
process.exit(1);
}
} else {
console.error('Usage: npx tsx scripts/search-lore.ts search|npc ...');
console.error(' search "<query>" [limit]');
console.error(' npc "<name>" "<question>" [limit]');
process.exit(2);
}
}
await main();