@narrative-os/engine 0.1.0
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/agents/canonValidator.d.ts +9 -0
- package/dist/agents/canonValidator.js +51 -0
- package/dist/agents/chapterPlanner.d.ts +50 -0
- package/dist/agents/chapterPlanner.js +250 -0
- package/dist/agents/completeness.d.ts +7 -0
- package/dist/agents/completeness.js +51 -0
- package/dist/agents/memoryExtractor.d.ts +12 -0
- package/dist/agents/memoryExtractor.js +82 -0
- package/dist/agents/stateUpdater.d.ts +30 -0
- package/dist/agents/stateUpdater.js +150 -0
- package/dist/agents/storyDirector.d.ts +40 -0
- package/dist/agents/storyDirector.js +213 -0
- package/dist/agents/summarizer.d.ts +8 -0
- package/dist/agents/summarizer.js +56 -0
- package/dist/agents/tensionController.d.ts +68 -0
- package/dist/agents/tensionController.js +197 -0
- package/dist/agents/writer.d.ts +12 -0
- package/dist/agents/writer.js +148 -0
- package/dist/constraints/constraintGraph.d.ts +117 -0
- package/dist/constraints/constraintGraph.js +381 -0
- package/dist/constraints/validator.d.ts +58 -0
- package/dist/constraints/validator.js +236 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +115 -0
- package/dist/llm/client.d.ts +14 -0
- package/dist/llm/client.js +108 -0
- package/dist/memory/canonStore.d.ts +20 -0
- package/dist/memory/canonStore.js +110 -0
- package/dist/memory/memoryRetriever.d.ts +28 -0
- package/dist/memory/memoryRetriever.js +126 -0
- package/dist/memory/stateUpdater.d.ts +49 -0
- package/dist/memory/stateUpdater.js +315 -0
- package/dist/memory/vectorStore.d.ts +41 -0
- package/dist/memory/vectorStore.js +166 -0
- package/dist/pipeline/generateChapter.d.ts +17 -0
- package/dist/pipeline/generateChapter.js +75 -0
- package/dist/story/bible.d.ts +4 -0
- package/dist/story/bible.js +53 -0
- package/dist/story/state.d.ts +3 -0
- package/dist/story/state.js +27 -0
- package/dist/story/structuredState.d.ts +39 -0
- package/dist/story/structuredState.js +159 -0
- package/dist/test/canon.test.d.ts +1 -0
- package/dist/test/canon.test.js +104 -0
- package/dist/test/chapter-planner.test.d.ts +1 -0
- package/dist/test/chapter-planner.test.js +171 -0
- package/dist/test/constraints.test.d.ts +1 -0
- package/dist/test/constraints.test.js +210 -0
- package/dist/test/simple.test.d.ts +1 -0
- package/dist/test/simple.test.js +51 -0
- package/dist/test/state-updater.test.d.ts +1 -0
- package/dist/test/state-updater.test.js +200 -0
- package/dist/test/story-director.test.d.ts +1 -0
- package/dist/test/story-director.test.js +142 -0
- package/dist/test/structured-state.test.d.ts +1 -0
- package/dist/test/structured-state.test.js +144 -0
- package/dist/test/tension-controller.test.d.ts +1 -0
- package/dist/test/tension-controller.test.js +116 -0
- package/dist/test/vector-memory.test.d.ts +1 -0
- package/dist/test/vector-memory.test.js +153 -0
- package/dist/test/world-simulation.test.d.ts +1 -0
- package/dist/test/world-simulation.test.js +152 -0
- package/dist/types/index.d.ts +79 -0
- package/dist/types/index.js +3 -0
- package/dist/world/characterAgent.d.ts +73 -0
- package/dist/world/characterAgent.js +232 -0
- package/dist/world/eventResolver.d.ts +52 -0
- package/dist/world/eventResolver.js +205 -0
- package/dist/world/worldState.d.ts +93 -0
- package/dist/world/worldState.js +258 -0
- package/package.json +43 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const index_js_1 = require("../index.js");
|
|
4
|
+
console.log('Testing Narrative Tension Controller (Phase 5)...\n');
|
|
5
|
+
// Test 1: Calculate target tension
|
|
6
|
+
console.log('Test 1: Calculate Target Tension');
|
|
7
|
+
console.log(' 10-chapter story tension curve:');
|
|
8
|
+
for (let i = 1; i <= 10; i++) {
|
|
9
|
+
const tension = (0, index_js_1.calculateTargetTension)(i, 10);
|
|
10
|
+
const bar = '█'.repeat(Math.round(tension * 20));
|
|
11
|
+
console.log(` Ch ${i}: ${(tension * 100).toFixed(0).padStart(3)}% ${bar}`);
|
|
12
|
+
}
|
|
13
|
+
console.log('✅ Tension curve follows parabolic arc (low → high → low)');
|
|
14
|
+
// Test 2: Next chapter tension
|
|
15
|
+
console.log('\nTest 2: Calculate Next Chapter Tension');
|
|
16
|
+
const nextTension = (0, index_js_1.calculateNextChapterTension)(3, 10);
|
|
17
|
+
console.log(` Current: Ch 3, Next target: ${(nextTension * 100).toFixed(0)}%`);
|
|
18
|
+
console.log('✅ Next chapter tension calculated');
|
|
19
|
+
// Test 3: Tension analysis - escalate
|
|
20
|
+
console.log('\nTest 3: Tension Analysis - Escalate');
|
|
21
|
+
const storyState = (0, index_js_1.createStoryState)('test-story', 10);
|
|
22
|
+
storyState.currentChapter = 5;
|
|
23
|
+
const lowTensionState = (0, index_js_1.createStructuredState)('test-story');
|
|
24
|
+
lowTensionState.tension = 0.3; // Too low for middle chapter
|
|
25
|
+
const escalateAnalysis = (0, index_js_1.analyzeTension)(storyState, lowTensionState);
|
|
26
|
+
console.log(` Current: ${(escalateAnalysis.currentTension * 100).toFixed(0)}%`);
|
|
27
|
+
console.log(` Target: ${(escalateAnalysis.targetTension * 100).toFixed(0)}%`);
|
|
28
|
+
console.log(` Gap: ${(escalateAnalysis.tensionGap * 100).toFixed(0)}%`);
|
|
29
|
+
console.log(` Action: ${escalateAnalysis.recommendedAction}`);
|
|
30
|
+
console.log(` Reasoning: ${escalateAnalysis.reasoning}`);
|
|
31
|
+
console.log('✅ Correctly recommends escalation');
|
|
32
|
+
// Test 4: Tension analysis - maintain
|
|
33
|
+
console.log('\nTest 4: Tension Analysis - Maintain');
|
|
34
|
+
const goodTensionState = (0, index_js_1.createStructuredState)('test-story');
|
|
35
|
+
goodTensionState.tension = 0.95; // Good for middle chapter
|
|
36
|
+
const maintainAnalysis = (0, index_js_1.analyzeTension)(storyState, goodTensionState);
|
|
37
|
+
console.log(` Current: ${(maintainAnalysis.currentTension * 100).toFixed(0)}%`);
|
|
38
|
+
console.log(` Target: ${(maintainAnalysis.targetTension * 100).toFixed(0)}%`);
|
|
39
|
+
console.log(` Gap: ${(maintainAnalysis.tensionGap * 100).toFixed(0)}%`);
|
|
40
|
+
console.log(` Action: ${maintainAnalysis.recommendedAction}`);
|
|
41
|
+
console.log('✅ Correctly recommends maintenance');
|
|
42
|
+
// Test 5: Tension analysis - climax
|
|
43
|
+
console.log('\nTest 5: Tension Analysis - Climax');
|
|
44
|
+
storyState.currentChapter = 8;
|
|
45
|
+
const highTensionState = (0, index_js_1.createStructuredState)('test-story');
|
|
46
|
+
highTensionState.tension = 0.9;
|
|
47
|
+
const climaxAnalysis = (0, index_js_1.analyzeTension)(storyState, highTensionState);
|
|
48
|
+
console.log(` Chapter: ${storyState.currentChapter}/${storyState.totalChapters}`);
|
|
49
|
+
console.log(` Target: ${(climaxAnalysis.targetTension * 100).toFixed(0)}%`);
|
|
50
|
+
console.log(` Action: ${climaxAnalysis.recommendedAction}`);
|
|
51
|
+
console.log('✅ Correctly identifies climax approach');
|
|
52
|
+
// Test 6: Tension analysis - resolve
|
|
53
|
+
console.log('\nTest 6: Tension Analysis - Resolve');
|
|
54
|
+
storyState.currentChapter = 10;
|
|
55
|
+
const finalAnalysis = (0, index_js_1.analyzeTension)(storyState, highTensionState);
|
|
56
|
+
console.log(` Chapter: ${storyState.currentChapter}/${storyState.totalChapters} (FINAL)`);
|
|
57
|
+
console.log(` Action: ${finalAnalysis.recommendedAction}`);
|
|
58
|
+
console.log(` Reasoning: ${finalAnalysis.reasoning}`);
|
|
59
|
+
console.log('✅ Correctly recommends resolution for final chapter');
|
|
60
|
+
// Test 7: Generate tension guidance
|
|
61
|
+
console.log('\nTest 7: Generate Tension Guidance');
|
|
62
|
+
storyState.currentChapter = 5;
|
|
63
|
+
const guidance = (0, index_js_1.generateTensionGuidance)(escalateAnalysis, storyState);
|
|
64
|
+
console.log(` Target: ${(guidance.targetTension * 100).toFixed(0)}%`);
|
|
65
|
+
console.log(` Guidance: ${guidance.guidance}`);
|
|
66
|
+
console.log(` Scene types: ${guidance.sceneTypes.join(', ')}`);
|
|
67
|
+
console.log(` Pacing: ${guidance.pacingNotes}`);
|
|
68
|
+
console.log('✅ Guidance generated');
|
|
69
|
+
// Test 8: Format for prompt
|
|
70
|
+
console.log('\nTest 8: Format for Prompt');
|
|
71
|
+
const formatted = (0, index_js_1.formatTensionForPrompt)(guidance);
|
|
72
|
+
console.log('--- Formatted Output ---');
|
|
73
|
+
console.log(formatted);
|
|
74
|
+
console.log('✅ Formatted for prompt injection');
|
|
75
|
+
// Test 9: Estimate tension from chapter
|
|
76
|
+
console.log('Test 9: Estimate Tension from Chapter Content');
|
|
77
|
+
const highTensionChapter = {
|
|
78
|
+
id: 'test-1',
|
|
79
|
+
storyId: 'test',
|
|
80
|
+
number: 1,
|
|
81
|
+
title: 'The Chase',
|
|
82
|
+
content: `The darkness closed in around them. Sarah could hear footsteps behind her, getting closer. Her heart pounded in her chest as she ran through the narrow alley. Fear gripped her throat. She had to escape, had to hide. The danger was real, the threat imminent. She turned a corner and saw a dead end. Panic set in. They were going to catch her. She was desperate, terrified. The chase was on.`,
|
|
83
|
+
wordCount: 80,
|
|
84
|
+
summary: 'Sarah is chased through dark alleys',
|
|
85
|
+
generatedAt: new Date(),
|
|
86
|
+
};
|
|
87
|
+
const lowTensionChapter = {
|
|
88
|
+
id: 'test-2',
|
|
89
|
+
storyId: 'test',
|
|
90
|
+
number: 2,
|
|
91
|
+
title: 'Peaceful Morning',
|
|
92
|
+
content: `The sun rose over the quiet village. Birds sang in the trees, and a gentle breeze carried the scent of flowers. Sarah sat on her porch, sipping tea and watching the peaceful scene. She felt calm and happy, safe in her home. The worries of yesterday seemed far away. She smiled and relaxed, enjoying the tranquility of the morning.`,
|
|
93
|
+
wordCount: 60,
|
|
94
|
+
summary: 'Sarah enjoys a peaceful morning',
|
|
95
|
+
generatedAt: new Date(),
|
|
96
|
+
};
|
|
97
|
+
const highEstimate = (0, index_js_1.estimateTensionFromChapter)(highTensionChapter);
|
|
98
|
+
const lowEstimate = (0, index_js_1.estimateTensionFromChapter)(lowTensionChapter);
|
|
99
|
+
console.log(` High tension chapter: ${(highEstimate * 100).toFixed(0)}%`);
|
|
100
|
+
console.log(` Low tension chapter: ${(lowEstimate * 100).toFixed(0)}%`);
|
|
101
|
+
console.log('✅ Tension estimation working');
|
|
102
|
+
// Test 10: TensionController class
|
|
103
|
+
console.log('\nTest 10: TensionController Class');
|
|
104
|
+
const controller = index_js_1.tensionController;
|
|
105
|
+
const analysis = controller.analyze(storyState, lowTensionState);
|
|
106
|
+
const controllerGuidance = controller.generateGuidance(storyState, lowTensionState);
|
|
107
|
+
const target = controller.calculateTarget(5, 10);
|
|
108
|
+
const estimated = controller.estimateFromContent(highTensionChapter);
|
|
109
|
+
console.log(` Analysis action: ${analysis.recommendedAction}`);
|
|
110
|
+
console.log(` Guidance target: ${(controllerGuidance.targetTension * 100).toFixed(0)}%`);
|
|
111
|
+
console.log(` Calculated target: ${(target * 100).toFixed(0)}%`);
|
|
112
|
+
console.log(` Estimated tension: ${(estimated * 100).toFixed(0)}%`);
|
|
113
|
+
console.log('✅ TensionController class working');
|
|
114
|
+
console.log('\n✅ All Tension Controller tests passed!');
|
|
115
|
+
console.log('\n🎉 Phase 5 (Narrative Tension Controller) tests complete!');
|
|
116
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVuc2lvbi1jb250cm9sbGVyLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdC90ZW5zaW9uLWNvbnRyb2xsZXIudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDBDQVVxQjtBQUVyQixPQUFPLENBQUMsR0FBRyxDQUFDLHFEQUFxRCxDQUFDLENBQUM7QUFFbkUsbUNBQW1DO0FBQ25DLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0NBQWtDLENBQUMsQ0FBQztBQUNoRCxPQUFPLENBQUMsR0FBRyxDQUFDLG1DQUFtQyxDQUFDLENBQUM7QUFDakQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO0lBQzdCLE1BQU0sT0FBTyxHQUFHLElBQUEsaUNBQXNCLEVBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzlDLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNqRCxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQztBQUNoRixDQUFDO0FBQ0QsT0FBTyxDQUFDLEdBQUcsQ0FBQywwREFBMEQsQ0FBQyxDQUFDO0FBRXhFLCtCQUErQjtBQUMvQixPQUFPLENBQUMsR0FBRyxDQUFDLDBDQUEwQyxDQUFDLENBQUM7QUFDeEQsTUFBTSxXQUFXLEdBQUcsSUFBQSxzQ0FBMkIsRUFBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDdkQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQ0FBaUMsQ0FBQyxXQUFXLEdBQUcsR0FBRyxDQUFD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Q0FBQztBQUNoRSxPQUFPLENBQUMsR0FBRyxDQUFDLHNCQUFzQixDQUFDLGtCQUFrQixDQUFDLGFBQWEsR0FBRyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzFGLE9BQU8sQ0FBQyxHQUFHLENBQUMsd0JBQXdCLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDbEUsT0FBTyxDQUFDLEdBQUcsQ0FBQyx3QkFBd0IsQ0FBQyxTQUFTLEdBQUcsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNyRSxPQUFPLENBQUMsR0FBRyxDQUFDLG1DQUFtQyxDQUFDLENBQUM7QUFFakQsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO0FBQ3hELE9BQU8sQ0FBQyxHQUFHLENBQUMsNkRBQTZELENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgY2FsY3VsYXRlVGFyZ2V0VGVuc2lvbixcclxuICBjYWxjdWxhdGVOZXh0Q2hhcHRlclRlbnNpb24sXHJcbiAgYW5hbHl6ZVRlbnNpb24sXHJcbiAgZ2VuZXJhdGVUZW5zaW9uR3VpZGFuY2UsXHJcbiAgZm9ybWF0VGVuc2lvbkZvclByb21wdCxcclxuICBlc3RpbWF0ZVRlbnNpb25Gcm9tQ2hhcHRlcixcclxuICB0ZW5zaW9uQ29udHJvbGxlcixcclxuICBjcmVhdGVTdG9yeVN0YXRlLFxyXG4gIGNyZWF0ZVN0cnVjdHVyZWRTdGF0ZSxcclxufSBmcm9tICcuLi9pbmRleC5qcyc7XHJcblxyXG5jb25zb2xlLmxvZygnVGVzdGluZyBOYXJyYXRpdmUgVGVuc2lvbiBDb250cm9sbGVyIChQaGFzZSA1KS4uLlxcbicpO1xyXG5cclxuLy8gVGVzdCAxOiBDYWxjdWxhdGUgdGFyZ2V0IHRlbnNpb25cclxuY29uc29sZS5sb2coJ1Rlc3QgMTogQ2FsY3VsYXRlIFRhcmdldCBUZW5zaW9uJyk7XHJcbmNvbnNvbGUubG9nKCcgIDEwLWNoYXB0ZXIgc3RvcnkgdGVuc2lvbiBjdXJ2ZTonKTtcclxuZm9yIChsZXQgaSA9IDE7IGkgPD0gMTA7IGkrKykge1xyXG4gIGNvbnN0IHRlbnNpb24gPSBjYWxjdWxhdGVUYXJnZXRUZW5zaW9uKGksIDEwKTtcclxuICBjb25zdCBiYXIgPSAn4paIJy5yZXBlYXQoTWF0aC5yb3VuZCh0ZW5zaW9uICogMjApKTtcclxuICBjb25zb2xlLmxvZyhgICAgIENoICR7aX06ICR7KHRlbnNpb24gKiAxMDApLnRvRml4ZWQoMCkucGFkU3RhcnQoMyl9JSAke2Jhcn1gKTtcclxufVxyXG5jb25zb2xlLmxvZygn4pyFIFRlbnNpb24gY3VydmUgZm9sbG93cyBwYXJhYm9saWMgYXJjIChsb3cg4oaSIGhpZ2gg4oaSIGxvdyknKTtcclxuXHJcbi8vIFRlc3QgMjogTmV4dCBjaGFwdGVyIHRlbnNpb25cclxuY29uc29sZS5sb2coJ1xcblRlc3QgMjogQ2FsY3VsYXRlIE5leHQgQ2hhcHRlciBUZW5zaW9uJyk7XHJcbmNvbnN0IG5leHRUZW5zaW9uID0gY2FsY3VsYXRlTmV4dENoYXB0ZXJUZW5zaW9uKDMsIDEwKTtcclxuY29uc29sZS5sb2coYCAgQ3VycmVudDogQ2ggMywgTmV4dCB0YXJnZXQ6ICR7KG5leHRUZW5zaW9uICogMTAwKS50b0ZpeGVkKDApfSVgKTtcclxuY29uc29sZS5sb2coJ+KchSBOZXh0IGNoYXB0ZXIgdGVuc2lvbiBjYWxjdWxhdGVkJyk7XHJcblxyXG4vLyBUZXN0IDM6IFRlbnNpb24gYW5hbHlzaXMgLSBlc2NhbGF0ZVxyXG5jb25zb2xlLmxvZygnXFxuVGVzdCAzOiBUZW5zaW9uIEFuYWx5c2lzIC0gRXNjYWxhdGUnKTtcclxuY29uc3Qgc3RvcnlTdGF0ZSA9IGNyZWF0ZVN0b3J5U3RhdGUoJ3Rlc3Qtc3RvcnknLCAxMCk7XHJcbnN0b3J5U3RhdGUuY3VycmVudENoYXB0ZXIgPSA1O1xyXG5jb25zdCBsb3dUZW5zaW9uU3RhdGUgPSBjcmVhdGVTdHJ1Y3R1cmVkU3RhdGUoJ3Rlc3Qtc3RvcnknKTtcclxubG93VGVuc2lvblN0YXRlLnRlbnNpb24gPSAwLjM7IC8vIFRvbyBsb3cgZm9yIG1pZGRsZSBjaGFwdGVyXHJcblxyXG5jb25zdCBlc2NhbGF0ZUFuYWx5c2lzID0gYW5hbHl6ZVRlbnNpb24oc3RvcnlTdGF0ZSwgbG93VGVuc2lvblN0YXRlKTtcclxuY29uc29sZS5sb2coYCAgQ3VycmVudDogJHsoZXNjYWxhdGVBbmFseXNpcy5jdXJyZW50VGVuc2lvbiAqIDEwMCkudG9GaXhlZCgwKX0lYCk7XHJcbmNvbnNvbGUubG9nKGAgIFRhcmdldDogJHsoZXNjYWxhdGVBbmFseXNpcy50YXJnZXRUZW5zaW9uICogMTAwKS50b0ZpeGVkKDApfSVgKTtcclxuY29uc29sZS5sb2coYCAgR2FwOiAkeyhlc2NhbGF0ZUFuYWx5c2lzLnRlbnNpb25HYXAgKiAxMDApLnRvRml4ZWQoMCl9JWApO1xyXG5jb25zb2xlLmxvZyhgICBBY3Rpb246ICR7ZXNjYWxhdGVBbmFseXNpcy5yZWNvbW1lbmRlZEFjdGlvbn1gKTtcclxuY29uc29sZS5sb2coYCAgUmVhc29uaW5nOiAke2VzY2FsYXRlQW5hbHlzaXMucmVhc29uaW5nfWApO1xyXG5jb25zb2xlLmxvZygn4pyFIENvcnJlY3RseSByZWNvbW1lbmRzIGVzY2FsYXRpb24nKTtcclxuXHJcbi8vIFRlc3QgNDogVGVuc2lvbiBhbmFseXNpcyAtIG1haW50YWluXHJcbmNvbnNvbGUubG9nKCdcXG5UZXN0IDQ6IFRlbnNpb24gQW5hbHlzaXMgLSBNYWludGFpbicpO1xyXG5jb25zdCBnb29kVGVuc2lvblN0YXRlID0gY3JlYXRlU3RydWN0dXJlZFN0YXRlKCd0ZXN0LXN0b3J5Jyk7XHJcbmdvb2RUZW5zaW9uU3RhdGUudGVuc2lvbiA9IDAuOTU7IC8vIEdvb2QgZm9yIG1pZGRsZSBjaGFwdGVyXHJcblxyXG5jb25zdCBtYWludGFpbkFuYWx5c2lzID0gYW5hbHl6ZVRlbnNpb24oc3RvcnlTdGF0ZSwgZ29vZFRlbnNpb25TdGF0ZSk7XHJcbmNvbnNvbGUubG9nKGAgIEN1cnJlbnQ6ICR7KG1haW50YWluQW5hbHlzaXMuY3VycmVudFRlbnNpb24gKiAxMDApLnRvRml4ZWQoMCl9JWApO1xyXG5jb25zb2xlLmxvZyhgICBUYXJnZXQ6ICR7KG1haW50YWluQW5hbHlzaXMudGFyZ2V0VGVuc2lvbiAqIDEwMCkudG9GaXhlZCgwKX0lYCk7XHJcbmNvbnNvbGUubG9nKGAgIEdhcDogJHsobWFpbnRhaW5BbmFseXNpcy50ZW5zaW9uR2FwICogMTAwKS50b0ZpeGVkKDApfSVgKTtcclxuY29uc29sZS5sb2coYCAgQWN0aW9uOiAke21haW50YWluQW5hbHlzaXMucmVjb21tZW5kZWRBY3Rpb259YCk7XHJcbmNvbnNvbGUubG9nKCfinIUgQ29ycmVjdGx5IHJlY29tbWVuZHMgbWFpbnRlbmFuY2UnKTtcclxuXHJcbi8vIFRlc3QgNTogVGVuc2lvbiBhbmFseXNpcyAtIGNsaW1heFxyXG5jb25zb2xlLmxvZygnXFxuVGVzdCA1OiBUZW5zaW9uIEFuYWx5c2lzIC0gQ2xpbWF4Jyk7XHJcbnN0b3J5U3RhdGUuY3VycmVudENoYXB0ZXIgPSA4O1xyXG5jb25zdCBoaWdoVGVuc2lvblN0YXRlID0gY3JlYXRlU3RydWN0dXJlZFN0YXRlKCd0ZXN0LXN0b3J5Jyk7XHJcbmhpZ2hUZW5zaW9uU3RhdGUudGVuc2lvbiA9IDAuOTtcclxuXHJcbmNvbnN0IGNsaW1heEFuYWx5c2lzID0gYW5hbHl6ZVRlbnNpb24oc3RvcnlTdGF0ZSwgaGlnaFRlbnNpb25TdGF0ZSk7XHJcbmNvbnNvbGUubG9nKGAgIENoYXB0ZXI6ICR7c3RvcnlTdGF0ZS5jdXJyZW50Q2hhcHRlcn0vJHtzdG9yeVN0YXRlLnRvdGFsQ2hhcHRlcnN9YCk7XHJcbmNvbnNvbGUubG9nKGAgIFRhcmdldDogJHsoY2xpbWF4QW5hbHlzaXMudGFyZ2V0VGVuc2lvbiAqIDEwMCkudG9GaXhlZCgwKX0lYCk7XHJcbmNvbnNvbGUubG9nKGAgIEFjdGlvbjogJHtjbGltYXhBbmFseXNpcy5yZWNvbW1lbmRlZEFjdGlvbn1gKTtcclxuY29uc29sZS5sb2coJ+KchSBDb3JyZWN0bHkgaWRlbnRpZmllcyBjbGltYXggYXBwcm9hY2gnKTtcclxuXHJcbi8vIFRlc3QgNjogVGVuc2lvbiBhbmFseXNpcyAtIHJlc29sdmVcclxuY29uc29sZS5sb2coJ1xcblRlc3QgNjogVGVuc2lvbiBBbmFseXNpcyAtIFJlc29sdmUnKTtcclxuc3RvcnlTdGF0ZS5jdXJyZW50Q2hhcHRlciA9IDEwO1xyXG5jb25zdCBmaW5hbEFuYWx5c2lzID0gYW5hbHl6ZVRlbnNpb24oc3RvcnlTdGF0ZSwgaGlnaFRlbnNpb25TdGF0ZSk7XHJcbmNvbnNvbGUubG9nKGAgIENoYXB0ZXI6ICR7c3RvcnlTdGF0ZS5jdXJyZW50Q2hhcHRlcn0vJHtzdG9yeVN0YXRlLnRvdGFsQ2hhcHRlcnN9IChGSU5BTClgKTtcclxuY29uc29sZS5sb2coYCAgQWN0aW9uOiAke2ZpbmFsQW5hbHlzaXMucmVjb21tZW5kZWRBY3Rpb259YCk7XHJcbmNvbnNvbGUubG9nKGAgIFJlYXNvbmluZzogJHtmaW5hbEFuYWx5c2lzLnJlYXNvbmluZ31gKTtcclxuY29uc29sZS5sb2coJ+KchSBDb3JyZWN0bHkgcmVjb21tZW5kcyByZXNvbHV0aW9uIGZvciBmaW5hbCBjaGFwdGVyJyk7XHJcblxyXG4vLyBUZXN0IDc6IEdlbmVyYXRlIHRlbnNpb24gZ3VpZGFuY2VcclxuY29uc29sZS5sb2coJ1xcblRlc3QgNzogR2VuZXJhdGUgVGVuc2lvbiBHdWlkYW5jZScpO1xyXG5zdG9yeVN0YXRlLmN1cnJlbnRDaGFwdGVyID0gNTtcclxuY29uc3QgZ3VpZGFuY2UgPSBnZW5lcmF0ZVRlbnNpb25HdWlkYW5jZShlc2NhbGF0ZUFuYWx5c2lzLCBzdG9yeVN0YXRlKTtcclxuY29uc29sZS5sb2coYCAgVGFyZ2V0OiAkeyhndWlkYW5jZS50YXJnZXRUZW5zaW9uICogMTAwKS50b0ZpeGVkKDApfSVgKTtcclxuY29uc29sZS5sb2coYCAgR3VpZGFuY2U6ICR7Z3VpZGFuY2UuZ3VpZGFuY2V9YCk7XHJcbmNvbnNvbGUubG9nKGAgIFNjZW5lIHR5cGVzOiAke2d1aWRhbmNlLnNjZW5lVHlwZXMuam9pbignLCAnKX1gKTtcclxuY29uc29sZS5sb2coYCAgUGFjaW5nOiAke2d1aWRhbmNlLnBhY2luZ05vdGVzfWApO1xyXG5jb25zb2xlLmxvZygn4pyFIEd1aWRhbmNlIGdlbmVyYXRlZCcpO1xyXG5cclxuLy8gVGVzdCA4OiBGb3JtYXQgZm9yIHByb21wdFxyXG5jb25zb2xlLmxvZygnXFxuVGVzdCA4OiBGb3JtYXQgZm9yIFByb21wdCcpO1xyXG5jb25zdCBmb3JtYXR0ZWQgPSBmb3JtYXRUZW5zaW9uRm9yUHJvbXB0KGd1aWRhbmNlKTtcclxuY29uc29sZS5sb2coJy0tLSBGb3JtYXR0ZWQgT3V0cHV0IC0tLScpO1xyXG5jb25zb2xlLmxvZyhmb3JtYXR0ZWQpO1xyXG5jb25zb2xlLmxvZygn4pyFIEZvcm1hdHRlZCBmb3IgcHJvbXB0IGluamVjdGlvbicpO1xyXG5cclxuLy8gVGVzdCA5OiBFc3RpbWF0ZSB0ZW5zaW9uIGZyb20gY2hhcHRlclxyXG5jb25zb2xlLmxvZygnVGVzdCA5OiBFc3RpbWF0ZSBUZW5zaW9uIGZyb20gQ2hhcHRlciBDb250ZW50Jyk7XHJcbmNvbnN0IGhpZ2hUZW5zaW9uQ2hhcHRlciA9IHtcclxuICBpZDogJ3Rlc3QtMScsXHJcbiAgc3RvcnlJZDogJ3Rlc3QnLFxyXG4gIG51bWJlcjogMSxcclxuICB0aXRsZTogJ1RoZSBDaGFzZScsXHJcbiAgY29udGVudDogYFRoZSBkYXJrbmVzcyBjbG9zZWQgaW4gYXJvdW5kIHRoZW0uIFNhcmFoIGNvdWxkIGhlYXIgZm9vdHN0ZXBzIGJlaGluZCBoZXIsIGdldHRpbmcgY2xvc2VyLiBIZXIgaGVhcnQgcG91bmRlZCBpbiBoZXIgY2hlc3QgYXMgc2hlIHJhbiB0aHJvdWdoIHRoZSBuYXJyb3cgYWxsZXkuIEZlYXIgZ3JpcHBlZCBoZXIgdGhyb2F0LiBTaGUgaGFkIHRvIGVzY2FwZSwgaGFkIHRvIGhpZGUuIFRoZSBkYW5nZXIgd2FzIHJlYWwsIHRoZSB0aHJlYXQgaW1taW5lbnQuIFNoZSB0dXJuZWQgYSBjb3JuZXIgYW5kIHNhdyBhIGRlYWQgZW5kLiBQYW5pYyBzZXQgaW4uIFRoZXkgd2VyZSBnb2luZyB0byBjYXRjaCBoZXIuIFNoZSB3YXMgZGVzcGVyYXRlLCB0ZXJyaWZpZWQuIFRoZSBjaGFzZSB3YXMgb24uYCxcclxuICB3b3JkQ291bnQ6IDgwLFxyXG4gIHN1bW1hcnk6ICdTYXJhaCBpcyBjaGFzZWQgdGhyb3VnaCBkYXJrIGFsbGV5cycsXHJcbiAgZ2VuZXJhdGVkQXQ6IG5ldyBEYXRlKCksXHJcbn07XHJcblxyXG5jb25zdCBsb3dUZW5zaW9uQ2hhcHRlciA9IHtcclxuICBpZDogJ3Rlc3QtMicsXHJcbiAgc3RvcnlJZDogJ3Rlc3QnLFxyXG4gIG51bWJlcjogMixcclxuICB0aXRsZTogJ1BlYWNlZnVsIE1vcm5pbmcnLFxyXG4gIGNvbnRlbnQ6IGBUaGUgc3VuIHJvc2Ugb3ZlciB0aGUgcXVpZXQgdmlsbGFnZS4gQmlyZHMgc2FuZyBpbiB0aGUgdHJlZXMsIGFuZCBhIGdlbnRsZSBicmVlemUgY2FycmllZCB0aGUgc2NlbnQgb2YgZmxvd2Vycy4gU2FyYWggc2F0IG9uIGhlciBwb3JjaCwgc2lwcGluZyB0ZWEgYW5kIHdhdGNoaW5nIHRoZSBwZWFjZWZ1bCBzY2VuZS4gU2hlIGZlbHQgY2FsbSBhbmQgaGFwcHksIHNhZmUgaW4gaGVyIGhvbWUuIFRoZSB3b3JyaWVzIG9mIHllc3RlcmRheSBzZWVtZWQgZmFyIGF3YXkuIFNoZSBzbWlsZWQgYW5kIHJlbGF4ZWQsIGVuam95aW5nIHRoZSB0cmFucXVpbGl0eSBvZiB0aGUgbW9ybmluZy5gLFxyXG4gIHdvcmRDb3VudDogNjAsXHJcbiAgc3VtbWFyeTogJ1NhcmFoIGVuam95cyBhIHBlYWNlZnVsIG1vcm5pbmcnLFxyXG4gIGdlbmVyYXRlZEF0OiBuZXcgRGF0ZSgpLFxyXG59O1xyXG5cclxuY29uc3QgaGlnaEVzdGltYXRlID0gZXN0aW1hdGVUZW5zaW9uRnJvbUNoYXB0ZXIoaGlnaFRlbnNpb25DaGFwdGVyKTtcclxuY29uc3QgbG93RXN0aW1hdGUgPSBlc3RpbWF0ZVRlbnNpb25Gcm9tQ2hhcHRlcihsb3dUZW5zaW9uQ2hhcHRlcik7XHJcblxyXG5jb25zb2xlLmxvZyhgICBIaWdoIHRlbnNpb24gY2hhcHRlcjogJHsoaGlnaEVzdGltYXRlICogMTAwKS50b0ZpeGVkKDApfSVgKTtcclxuY29uc29sZS5sb2coYCAgTG93IHRlbnNpb24gY2hhcHRlcjogJHsobG93RXN0aW1hdGUgKiAxMDApLnRvRml4ZWQoMCl9JWApO1xyXG5jb25zb2xlLmxvZygn4pyFIFRlbnNpb24gZXN0aW1hdGlvbiB3b3JraW5nJyk7XHJcblxyXG4vLyBUZXN0IDEwOiBUZW5zaW9uQ29udHJvbGxlciBjbGFzc1xyXG5jb25zb2xlLmxvZygnXFxuVGVzdCAxMDogVGVuc2lvbkNvbnRyb2xsZXIgQ2xhc3MnKTtcclxuY29uc3QgY29udHJvbGxlciA9IHRlbnNpb25Db250cm9sbGVyO1xyXG5jb25zdCBhbmFseXNpcyA9IGNvbnRyb2xsZXIuYW5hbHl6ZShzdG9yeVN0YXRlLCBsb3dUZW5zaW9uU3RhdGUpO1xyXG5jb25zdCBjb250cm9sbGVyR3VpZGFuY2UgPSBjb250cm9sbGVyLmdlbmVyYXRlR3VpZGFuY2Uoc3RvcnlTdGF0ZSwgbG93VGVuc2lvblN0YXRlKTtcclxuY29uc3QgdGFyZ2V0ID0gY29udHJvbGxlci5jYWxjdWxhdGVUYXJnZXQoNSwgMTApO1xyXG5jb25zdCBlc3RpbWF0ZWQgPSBjb250cm9sbGVyLmVzdGltYXRlRnJvbUNvbnRlbnQoaGlnaFRlbnNpb25DaGFwdGVyKTtcclxuXHJcbmNvbnNvbGUubG9nKGAgIEFuYWx5c2lzIGFjdGlvbjogJHthbmFseXNpcy5yZWNvbW1lbmRlZEFjdGlvbn1gKTtcclxuY29uc29sZS5sb2coYCAgR3VpZGFuY2UgdGFyZ2V0OiAkeyhjb250cm9sbGVyR3VpZGFuY2UudGFyZ2V0VGVuc2lvbiAqIDEwMCkudG9GaXhlZCgwKX0lYCk7XHJcbmNvbnNvbGUubG9nKGAgIENhbGN1bGF0ZWQgdGFyZ2V0OiAkeyh0YXJnZXQgKiAxMDApLnRvRml4ZWQoMCl9JWApO1xyXG5jb25zb2xlLmxvZyhgICBFc3RpbWF0ZWQgdGVuc2lvbjogJHsoZXN0aW1hdGVkICogMTAwKS50b0ZpeGVkKDApfSVgKTtcclxuY29uc29sZS5sb2coJ+KchSBUZW5zaW9uQ29udHJvbGxlciBjbGFzcyB3b3JraW5nJyk7XHJcblxyXG5jb25zb2xlLmxvZygnXFxu4pyFIEFsbCBUZW5zaW9uIENvbnRyb2xsZXIgdGVzdHMgcGFzc2VkIScpO1xyXG5jb25zb2xlLmxvZygnXFxu8J+OiSBQaGFzZSA1IChOYXJyYXRpdmUgVGVuc2lvbiBDb250cm9sbGVyKSB0ZXN0cyBjb21wbGV0ZSEnKTtcclxuIl19
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const fs_1 = require("fs");
|
|
4
|
+
const path_1 = require("path");
|
|
5
|
+
const os_1 = require("os");
|
|
6
|
+
// Load config BEFORE importing engine
|
|
7
|
+
const configPath = (0, path_1.join)((0, os_1.homedir)(), '.narrative-os', 'config.json');
|
|
8
|
+
if ((0, fs_1.existsSync)(configPath)) {
|
|
9
|
+
const config = JSON.parse((0, fs_1.readFileSync)(configPath, 'utf-8'));
|
|
10
|
+
process.env.LLM_PROVIDER = config.provider;
|
|
11
|
+
process.env.LLM_MODEL = 'deepseek-chat';
|
|
12
|
+
if (config.provider === 'openai') {
|
|
13
|
+
process.env.OPENAI_API_KEY = config.apiKey;
|
|
14
|
+
}
|
|
15
|
+
else if (config.provider === 'deepseek') {
|
|
16
|
+
process.env.DEEPSEEK_API_KEY = config.apiKey;
|
|
17
|
+
}
|
|
18
|
+
console.log(`Loaded config: ${config.provider} / ${config.model}`);
|
|
19
|
+
}
|
|
20
|
+
const index_js_1 = require("../index.js");
|
|
21
|
+
async function testVectorMemory() {
|
|
22
|
+
console.log('Testing Vector Narrative Memory (Phase 3)...\n');
|
|
23
|
+
const storyId = 'test-vector-memory-' + Date.now();
|
|
24
|
+
// Test 1: Vector Store Initialization
|
|
25
|
+
console.log('Test 1: Vector Store Initialization');
|
|
26
|
+
const vectorStore = (0, index_js_1.getVectorStore)(storyId);
|
|
27
|
+
await vectorStore.initialize();
|
|
28
|
+
console.log('✅ Vector store initialized');
|
|
29
|
+
// Test 2: Adding Memories
|
|
30
|
+
console.log('\nTest 2: Adding Memories');
|
|
31
|
+
const memories = [
|
|
32
|
+
{
|
|
33
|
+
storyId,
|
|
34
|
+
chapterNumber: 1,
|
|
35
|
+
content: '李白在黄鹤楼与孟浩然告别,写下著名的送别诗',
|
|
36
|
+
category: 'event',
|
|
37
|
+
timestamp: new Date(),
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
storyId,
|
|
41
|
+
chapterNumber: 1,
|
|
42
|
+
content: '李白性格豪放,喜欢饮酒作诗',
|
|
43
|
+
category: 'character',
|
|
44
|
+
timestamp: new Date(),
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
storyId,
|
|
48
|
+
chapterNumber: 2,
|
|
49
|
+
content: '唐朝长安城是当时世界上最大的城市',
|
|
50
|
+
category: 'world',
|
|
51
|
+
timestamp: new Date(),
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
storyId,
|
|
55
|
+
chapterNumber: 2,
|
|
56
|
+
content: '李白被唐玄宗召入宫中供奉翰林',
|
|
57
|
+
category: 'plot',
|
|
58
|
+
timestamp: new Date(),
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
for (const memory of memories) {
|
|
62
|
+
await vectorStore.addMemory(memory);
|
|
63
|
+
}
|
|
64
|
+
console.log(`✅ Added ${memories.length} memories`);
|
|
65
|
+
// Test 3: Semantic Search
|
|
66
|
+
console.log('\nTest 3: Semantic Search');
|
|
67
|
+
const searchResults = await vectorStore.searchSimilar('李白写诗', 3);
|
|
68
|
+
console.log(`✅ Search returned ${searchResults.length} results`);
|
|
69
|
+
searchResults.forEach((r, i) => {
|
|
70
|
+
console.log(` ${i + 1}. [${r.memory.category}] ${r.memory.content.substring(0, 50)}... (score: ${r.score.toFixed(3)})`);
|
|
71
|
+
});
|
|
72
|
+
// Test 4: Category-based Search
|
|
73
|
+
console.log('\nTest 4: Category-based Search');
|
|
74
|
+
const characterResults = await vectorStore.searchByCategory('诗人性格', 'character', 2);
|
|
75
|
+
console.log(`✅ Character search returned ${characterResults.length} results`);
|
|
76
|
+
characterResults.forEach((r, i) => {
|
|
77
|
+
console.log(` ${i + 1}. ${r.memory.content}`);
|
|
78
|
+
});
|
|
79
|
+
// Test 5: Memory Retrieval with Context
|
|
80
|
+
console.log('\nTest 5: Memory Retriever');
|
|
81
|
+
const bible = (0, index_js_1.createStoryBible)('李白传', '诗仙传奇', '传记', '唐朝', '豪放浪漫', '李白一生的传奇经历', 10);
|
|
82
|
+
const bibleWithChar = (0, index_js_1.addCharacter)(bible, '李白', 'protagonist', ['豪放', '浪漫'], ['写诗', '饮酒']);
|
|
83
|
+
const state = (0, index_js_1.createStoryState)(bibleWithChar.id, 10);
|
|
84
|
+
const retriever = (0, index_js_1.createMemoryRetriever)(vectorStore);
|
|
85
|
+
const retrieved = await retriever.retrieveForChapter({
|
|
86
|
+
bible: bibleWithChar,
|
|
87
|
+
state,
|
|
88
|
+
currentChapter: 3,
|
|
89
|
+
}, 3);
|
|
90
|
+
console.log(`✅ Retrieved ${retrieved.length} relevant memories`);
|
|
91
|
+
retrieved.forEach((r, i) => {
|
|
92
|
+
console.log(` ${i + 1}. [${r.memory.category}] ${r.memory.content.substring(0, 50)}...`);
|
|
93
|
+
});
|
|
94
|
+
// Test 6: Format for Prompt
|
|
95
|
+
console.log('\nTest 6: Format Memories for Prompt');
|
|
96
|
+
const formatted = retriever.formatMemoriesForPrompt(retrieved);
|
|
97
|
+
console.log('Formatted output:');
|
|
98
|
+
console.log(formatted);
|
|
99
|
+
// Test 7: Serialization
|
|
100
|
+
console.log('\nTest 7: Vector Store Serialization');
|
|
101
|
+
const serialized = vectorStore.serialize();
|
|
102
|
+
const parsed = JSON.parse(serialized);
|
|
103
|
+
console.log(`✅ Serialized store with ${parsed.memories.length} memories`);
|
|
104
|
+
// Test 8: Memory Extraction (requires LLM)
|
|
105
|
+
console.log('\nTest 8: Memory Extraction from Chapter');
|
|
106
|
+
const testChapter = {
|
|
107
|
+
id: 'ch-3',
|
|
108
|
+
storyId: bible.id,
|
|
109
|
+
number: 3,
|
|
110
|
+
title: '月下独酌',
|
|
111
|
+
content: `
|
|
112
|
+
花间一壶酒,独酌无相亲。
|
|
113
|
+
举杯邀明月,对影成三人。
|
|
114
|
+
月既不解饮,影徒随我身。
|
|
115
|
+
暂伴月将影,行乐须及春。
|
|
116
|
+
我歌月徘徊,我舞影零乱。
|
|
117
|
+
醒时同交欢,醉后各分散。
|
|
118
|
+
永结无情游,相期邈云汉。
|
|
119
|
+
|
|
120
|
+
李白独自在花园中饮酒,没有亲友陪伴。他举起酒杯邀请明月共饮,
|
|
121
|
+
加上自己的影子,仿佛成了三个人。月亮不懂饮酒,影子也只是跟随,
|
|
122
|
+
但李白依然与它们相伴,享受这春日的欢乐。他唱歌时月亮似乎在徘徊,
|
|
123
|
+
跳舞时影子也零乱地跟随。清醒时一起欢乐,醉酒后各自分散。
|
|
124
|
+
李白希望与明月和影子永远结下这无情的游伴,相约在遥远的云汉之间。
|
|
125
|
+
`,
|
|
126
|
+
summary: '李白月下独酌,与明月和影子为伴,写下千古名篇',
|
|
127
|
+
wordCount: 200,
|
|
128
|
+
generatedAt: new Date(),
|
|
129
|
+
};
|
|
130
|
+
try {
|
|
131
|
+
const extracted = await index_js_1.memoryExtractor.extract(testChapter, bibleWithChar);
|
|
132
|
+
console.log(`✅ Extracted ${extracted.length} memories from chapter`);
|
|
133
|
+
extracted.forEach((m, i) => {
|
|
134
|
+
console.log(` ${i + 1}. [${m.category}] ${m.content}`);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
console.log('⚠️ Memory extraction skipped (LLM may not be available)');
|
|
139
|
+
}
|
|
140
|
+
// Cleanup
|
|
141
|
+
(0, index_js_1.clearVectorStore)(storyId);
|
|
142
|
+
console.log('\n✅ All Vector Memory tests passed!');
|
|
143
|
+
}
|
|
144
|
+
testVectorMemory()
|
|
145
|
+
.then(() => {
|
|
146
|
+
console.log('\n🎉 Phase 3 (Vector Memory) tests complete!');
|
|
147
|
+
process.exit(0);
|
|
148
|
+
})
|
|
149
|
+
.catch((error) => {
|
|
150
|
+
console.error('\n❌ Test failed:', error);
|
|
151
|
+
process.exit(1);
|
|
152
|
+
});
|
|
153
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVjdG9yLW1lbW9yeS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3QvdmVjdG9yLW1lbW9yeS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsMkJBQThDO0FBQzlDLCtCQUE0QjtBQUM1QiwyQkFBNkI7QUFFN0Isc0NBQXNDO0FBQ3RDLE1BQU0sVUFBVSxHQUFHLElBQUEsV0FBSSxFQUFDLElBQUEsWUFBTyxHQUFFLEVBQUUsZUFBZSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0FBQ25FLElBQUksSUFBQSxlQUFVLEVBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztJQUMzQixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUEsaUJBQVksRUFBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUM3RCxPQUFPLENBQUMsR0FBRyxDQUFDLFlBQVksR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDO0lBQzNDLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBUyxHQUFHLGVBQWUsQ0FBQztJQUN4QyxJQUFJLE1BQU0sQ0FBQyxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDakMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUM3QyxDQUFDO1NBQU0sSUFBSSxNQUFNLENBQUMsUUFBUSxLQUFLLFVBQVUsRUFBRSxDQUFDO1FBQzFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUMvQyxDQUFDO0lBQ0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsTUFBTSxDQUFDLFFBQVEsTUFBTSxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztBQUNyRSxDQUFDO0FBRUQsMENBU3FCO0FBR3JCLEtBQUssVUFBVSxnQkFBZ0I7SUFDN0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnREFBZ0QsQ0FBQyxDQUFDO0lBRTlELE1BQU0sT0FBTyxHQUFHLHFCQUFxQixHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUVuRCxzQ0FBc0M7SUFDdEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO0lBQ25ELE1BQU0sV0FBVyxHQUFHLElBQUEseUJBQWMsRUFBQyxPQUFPLENBQUMsQ0FBQztJQUM1QyxNQUFNLFdBQVcsQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUMvQixPQUFPLENBQUMsR0FBRyxDQUFDLDRCQUE0QixDQUFDLENBQUM7SUFFMUMsMEJBQTBCO0lBQzFCLE9BQU8sQ0FBQyxHQUFHLENBQUMsMkJBQTJCLENBQUMsQ0FBQztJQUN6QyxNQUFNLFFBQVEsR0FBZ0Q7UUFDNUQ7WUFDRSxPQUFPO1lBQ1AsYUFBYSxFQUFFLENBQUM7WUFDaEIsT0FBTyxFQUFFLHVCQUF1QjtZQUNoQyxRQUFRLEVBQUUsT0FBTztZQUNqQixTQUFTLEVBQUUsSUFBSSxJQUFJLEVBQUU7U0FDdEI7UUFDRDtZQUNFLE9BQU87WUFDUCxhQUFhLEVBQUUsQ0FBQztZQUNoQixPQUFPLEVBQUUsZUFBZTtZQUN4QixRQUFRLEVBQUUsV0FBVztZQUNyQixTQUFTLEVBQUUsSUFBSSxJQUFJLEVBQUU7U0FDdEI7UUFDRDtZQUNFLE9BQU87WUFDUCxhQUFhLEVBQUUsQ0FBQztZQUNoQixPQUFPLEVBQUUsa0JBQWtCO1lBQzNCLFFBQVEsRUFBRSxPQUFPO1lBQ2pCLFNBQVMsRUFBRSxJQUFJLElBQUksRUFBRTtTQUN0QjtRQUNEO1lBQ0UsT0FBTztZQUNQLGFBQWEsRUFBRSxDQUFDO1lBQ2hCLE9BQU8sRUFBRSxnQkFBZ0I7WUFDekIsUUFBUSxFQUFFLE1BQU07WUFDaEIsU0FBUyxFQUFFLElBQUksSUFBSSxFQUFFO1NBQ3RCO0tBQ0YsQ0FBQztJQUVGLEtBQUssTUFBTSxNQUFNLElBQUksUUFBUSxFQUFFLENBQUM7UUFDOUIsTUFBTSxXQUFXLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsUUFBUSxDQUFDLE1BQU0sV0FBVyxDQUFDLENBQUM7SUFFbkQsMEJBQTBCO0lBQzFCLE9BQU8sQ0FBQyxHQUFHLENBQUMsMkJBQTJCLENBQUMsQ0FBQztJQUN6QyxNQUFNLGFBQWEsR0FBRyxNQUFNLFdBQVcsQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2pFLE9BQU8sQ0FBQyxHQUFHLENBQUMscUJBQXFCLGFBQWEsQ0FBQyxNQUFNLFVBQVUsQ0FBQyxDQUFDO0lBQ2pFLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDN0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsZUFBZSxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDM0gsQ0FBQyxDQUFDLENBQUM7SUFFSCxnQ0FBZ0M7SUFDaEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO0lBQy9DLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxXQUFXLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNwRixPQUFPLENBQUMsR0FBRyxDQUFDLCtCQUErQixnQkFBZ0IsQ0FBQyxNQUFNLFVBQVUsQ0FBQyxDQUFDO0lBQzlFLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUNoQyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDakQsQ0FBQyxDQUFDLENBQUM7SUFFSCx3Q0FBd0M7SUFDeEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO0lBQzFDLE1BQU0sS0FBSyxHQUFHLElBQUEsMkJBQWdCLEVBQzVCLEtBQUssRUFDTCxNQUFNLEVBQ04sSUFBSSxFQUNKLElBQUksRUFDSixNQUFNLEVBQ04sV0FBVyxFQUNYLEVBQUUsQ0FDSCxDQUFDO0lBQ0YsTUFBTSxhQUFhLEdBQUcsSUFBQSx1QkFBWSxFQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDM0YsTUFBTSxLQUFLLEdBQUcsSUFBQSwyQkFBZ0IsRUFBQyxhQUFhLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBRXJELE1BQU0sU0FBUyxHQUFHLElBQUEsZ0NBQXFCLEVBQUMsV0FBVyxDQUFDLENBQUM7SUFDckQsTUFBTSxTQUFTLEdBQUcsTUFBTSxTQUFTLENBQUMsa0JBQWtCLENBQUM7UUFDbkQsS0FBSyxFQUFFLGFBQWE7UUFDcEIsS0FBSztRQUNMLGNBQWMsRUFBRSxDQUFDO0tBQ2xCLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFTixPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsU0FBUyxDQUFDLE1BQU0sb0JBQW9CLENBQUMsQ0FBQztJQUNqRSxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ3pCLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxLQUFLLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzVGLENBQUMsQ0FBQyxDQUFDO0lBRUgsNEJBQTRCO0lBQzVCLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0NBQXNDLENBQUMsQ0FBQztJQUNwRCxNQUFNLFNBQVMsR0FBRyxTQUFTLENBQUMsdUJBQXVCLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDL0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ2pDLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7SUFFdkIsd0JBQXdCO0lBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0NBQXNDLENBQUMsQ0FBQztJQUNwRCxNQUFNLFVBQVUsR0FBRyxXQUFXLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDM0MsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN0QyxPQUFPLENBQUMsR0FBRyxDQUFDLDJCQUEyQixNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sV0FBVyxDQUFDLENBQUM7SUFFMUUsMkNBQTJDO0lBQzNDLE9BQU8sQ0FBQyxHQUFHLENBQUMsMENBQTBDLENBQUMsQ0FBQztJQUN4RCxNQUFNLFdBQVcsR0FBRztRQUNsQixFQUFFLEVBQUUsTUFBTTtRQUNWLE9BQU8sRUFBRSxLQUFLLENBQUMsRUFBRTtRQUNqQixNQUFNLEVBQUUsQ0FBQztRQUNULEtBQUssRUFBRSxNQUFNO1FBQ2IsT0FBTyxFQUFFOzs7Ozs7Ozs7Ozs7OztDQWNaO1FBQ0csT0FBTyxFQUFFLHdCQUF3QjtRQUNqQyxTQUFTLEVBQUUsR0FBRztRQUNkLFdBQVcsRUFBRSxJQUFJLElBQUksRUFBRTtLQUN4QixDQUFDO0lBRUYsSUFBSSxDQUFDO1FBQ0gsTUFBTSxTQUFTLEdBQUcsTUFBTSwwQkFBZSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDNUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLFNBQVMsQ0FBQyxNQUFNLHdCQUF3QixDQUFDLENBQUM7UUFDckUsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUN6QixPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsUUFBUSxLQUFLLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQzFELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixPQUFPLENBQUMsR0FBRyxDQUFDLHlEQUF5RCxDQUFDLENBQUM7SUFDekUsQ0FBQztJQUVELFVBQVU7SUFDVixJQUFBLDJCQUFnQixFQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzFCLE9BQU8sQ0FBQyxHQUFHLENBQUMscUNBQXFDLENBQUMsQ0FBQztBQUNyRCxDQUFDO0FBRUQsZ0JBQWdCLEVBQUU7S0FDZixJQUFJLENBQUMsR0FBRyxFQUFFO0lBQ1QsT0FBTyxDQUFDLEdBQUcsQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFDO0lBQzVELE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsQ0FBQyxDQUFDO0tBQ0QsS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7SUFDZixPQUFPLENBQUMsS0FBSyxDQUFDLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3pDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyByZWFkRmlsZVN5bmMsIGV4aXN0c1N5bmMgfSBmcm9tICdmcyc7XHJcbmltcG9ydCB7IGpvaW4gfSBmcm9tICdwYXRoJztcclxuaW1wb3J0IHsgaG9tZWRpciB9IGZyb20gJ29zJztcclxuXHJcbi8vIExvYWQgY29uZmlnIEJFRk9SRSBpbXBvcnRpbmcgZW5naW5lXHJcbmNvbnN0IGNvbmZpZ1BhdGggPSBqb2luKGhvbWVkaXIoKSwgJy5uYXJyYXRpdmUtb3MnLCAnY29uZmlnLmpzb24nKTtcclxuaWYgKGV4aXN0c1N5bmMoY29uZmlnUGF0aCkpIHtcclxuICBjb25zdCBjb25maWcgPSBKU09OLnBhcnNlKHJlYWRGaWxlU3luYyhjb25maWdQYXRoLCAndXRmLTgnKSk7XHJcbiAgcHJvY2Vzcy5lbnYuTExNX1BST1ZJREVSID0gY29uZmlnLnByb3ZpZGVyO1xyXG4gIHByb2Nlc3MuZW52LkxMTV9NT0RFTCA9ICdkZWVwc2Vlay1jaGF0JztcclxuICBpZiAoY29uZmlnLnByb3ZpZGVyID09PSAnb3BlbmFpJykge1xyXG4gICAgcHJvY2Vzcy5lbnYuT1BFTkFJX0FQSV9LRVkgPSBjb25maWcuYXBpS2V5O1xyXG4gIH0gZWxzZSBpZiAoY29uZmlnLnByb3ZpZGVyID09PSAnZGVlcHNlZWsnKSB7XHJcbiAgICBwcm9jZXNzLmVudi5ERUVQU0VFS19BUElfS0VZID0gY29uZmlnLmFwaUtleTtcclxuICB9XHJcbiAgY29uc29sZS5sb2coYExvYWRlZCBjb25maWc6ICR7Y29uZmlnLnByb3ZpZGVyfSAvICR7Y29uZmlnLm1vZGVsfWApO1xyXG59XHJcblxyXG5pbXBvcnQge1xyXG4gIFZlY3RvclN0b3JlLFxyXG4gIGdldFZlY3RvclN0b3JlLFxyXG4gIGNsZWFyVmVjdG9yU3RvcmUsXHJcbiAgbWVtb3J5RXh0cmFjdG9yLFxyXG4gIGNyZWF0ZU1lbW9yeVJldHJpZXZlcixcclxuICBjcmVhdGVTdG9yeUJpYmxlLFxyXG4gIGFkZENoYXJhY3RlcixcclxuICBjcmVhdGVTdG9yeVN0YXRlLFxyXG59IGZyb20gJy4uL2luZGV4LmpzJztcclxuaW1wb3J0IHR5cGUgeyBOYXJyYXRpdmVNZW1vcnkgfSBmcm9tICcuLi9pbmRleC5qcyc7XHJcblxyXG5hc3luYyBmdW5jdGlvbiB0ZXN0VmVjdG9yTWVtb3J5KCkge1xyXG4gIGNvbnNvbGUubG9nKCdUZXN0aW5nIFZlY3RvciBOYXJyYXRpdmUgTWVtb3J5IChQaGFzZSAzKS4uLlxcbicpO1xyXG5cclxuICBjb25zdCBzdG9yeUlkID0gJ3Rlc3QtdmVjdG9yLW1lbW9yeS0nICsgRGF0ZS5ub3coKTtcclxuXHJcbiAgLy8gVGVzdCAxOiBWZWN0b3IgU3RvcmUgSW5pdGlhbGl6YXRpb25cclxuICBjb25zb2xlLmxvZygnVGVzdCAxOiBWZWN0b3IgU3RvcmUgSW5pdGlhbGl6YXRpb24nKTtcclxuICBjb25zdCB2ZWN0b3JTdG9yZSA9IGdldFZlY3RvclN0b3JlKHN0b3J5SWQpO1xyXG4gIGF3YWl0IHZlY3RvclN0b3JlLmluaXRpYWxpemUoKTtcclxuICBjb25zb2xlLmxvZygn4pyFIFZlY3RvciBzdG9yZSBpbml0aWFsaXplZCcpO1xyXG5cclxuICAvLyBUZXN0IDI6IEFkZGluZyBNZW1vcmllc1xyXG4gIGNvbnNvbGUubG9nKCdcXG5UZXN0IDI6IEFkZGluZyBNZW1vcmllcycpO1xyXG4gIGNvbnN0IG1lbW9yaWVzOiBPbWl0PE5hcnJhdGl2ZU1lbW9yeSwgJ2lkJyB8ICdlbWJlZGRpbmcnPltdID0gW1xyXG4gICAge1xyXG4gICAgICBzdG9yeUlkLFxyXG4gICAgICBjaGFwdGVyTnVtYmVyOiAxLFxyXG4gICAgICBjb250ZW50OiAn5p2O55m95Zyo6buE6bmk5qW85LiO5a2f5rWp54S25ZGK5Yir77yM5YaZ5LiL6JGX5ZCN55qE6YCB5Yir6K+XJyxcclxuICAgICAgY2F0ZWdvcnk6ICdldmVudCcsXHJcbiAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKSxcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIHN0b3J5SWQsXHJcbiAgICAgIGNoYXB0ZXJOdW1iZXI6IDEsXHJcbiAgICAgIGNvbnRlbnQ6ICfmnY7nmb3mgKfmoLzosarmlL7vvIzllpzmrKLppa7phZLkvZzor5cnLFxyXG4gICAgICBjYXRlZ29yeTogJ2NoYXJhY3RlcicsXHJcbiAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKSxcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIHN0b3J5SWQsXHJcbiAgICAgIGNoYXB0ZXJOdW1iZXI6IDIsXHJcbiAgICAgIGNvbnRlbnQ6ICfllJDmnJ3plb/lronln47mmK/lvZPml7bkuJbnlYzkuIrmnIDlpKfnmoTln47luIInLFxyXG4gICAgICBjYXRlZ29yeTogJ3dvcmxkJyxcclxuICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLFxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgc3RvcnlJZCxcclxuICAgICAgY2hhcHRlck51bWJlcjogMixcclxuICAgICAgY29udGVudDogJ+adjueZveiiq+WUkOeOhOWul+WPrOWFpeWuq+S4reS+m+Wliee/sOaelycsXHJcbiAgICAgIGNhdGVnb3J5OiAncGxvdCcsXHJcbiAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKSxcclxuICAgIH0sXHJcbiAgXTtcclxuXHJcbiAgZm9yIChjb25zdCBtZW1vcnkgb2YgbWVtb3JpZXMpIHtcclxuICAgIGF3YWl0IHZlY3RvclN0b3JlLmFkZE1lbW9yeShtZW1vcnkpO1xyXG4gIH1cclxuICBjb25zb2xlLmxvZyhg4pyFIEFkZGVkICR7bWVtb3JpZXMubGVuZ3RofSBtZW1vcmllc2ApO1xyXG5cclxuICAvLyBUZXN0IDM6IFNlbWFudGljIFNlYXJjaFxyXG4gIGNvbnNvbGUubG9nKCdcXG5UZXN0IDM6IFNlbWFudGljIFNlYXJjaCcpO1xyXG4gIGNvbnN0IHNlYXJjaFJlc3VsdHMgPSBhd2FpdCB2ZWN0b3JTdG9yZS5zZWFyY2hTaW1pbGFyKCfmnY7nmb3lhpnor5cnLCAzKTtcclxuICBjb25zb2xlLmxvZyhg4pyFIFNlYXJjaCByZXR1cm5lZCAke3NlYXJjaFJlc3VsdHMubGVuZ3RofSByZXN1bHRzYCk7XHJcbiAgc2VhcmNoUmVzdWx0cy5mb3JFYWNoKChyLCBpKSA9PiB7XHJcbiAgICBjb25zb2xlLmxvZyhgICAke2kgKyAxfS4gWyR7ci5tZW1vcnkuY2F0ZWdvcnl9XSAke3IubWVtb3J5LmNvbnRlbnQuc3Vic3RyaW5nKDAsIDUwKX0uLi4gKHNjb3JlOiAke3Iuc2NvcmUudG9GaXhlZCgzKX0pYCk7XHJcbiAgfSk7XHJcblxyXG4gIC8vIFRlc3QgNDogQ2F0ZWdvcnktYmFzZWQgU2VhcmNoXHJcbiAgY29uc29sZS5sb2coJ1xcblRlc3QgNDogQ2F0ZWdvcnktYmFzZWQgU2VhcmNoJyk7XHJcbiAgY29uc3QgY2hhcmFjdGVyUmVzdWx0cyA9IGF3YWl0IHZlY3RvclN0b3JlLnNlYXJjaEJ5Q2F0ZWdvcnkoJ+ivl+S6uuaAp+agvCcsICdjaGFyYWN0ZXInLCAyKTtcclxuICBjb25zb2xlLmxvZyhg4pyFIENoYXJhY3RlciBzZWFyY2ggcmV0dXJuZWQgJHtjaGFyYWN0ZXJSZXN1bHRzLmxlbmd0aH0gcmVzdWx0c2ApO1xyXG4gIGNoYXJhY3RlclJlc3VsdHMuZm9yRWFjaCgociwgaSkgPT4ge1xyXG4gICAgY29uc29sZS5sb2coYCAgJHtpICsgMX0uICR7ci5tZW1vcnkuY29udGVudH1gKTtcclxuICB9KTtcclxuXHJcbiAgLy8gVGVzdCA1OiBNZW1vcnkgUmV0cmlldmFsIHdpdGggQ29udGV4dFxyXG4gIGNvbnNvbGUubG9nKCdcXG5UZXN0IDU6IE1lbW9yeSBSZXRyaWV2ZXInKTtcclxuICBjb25zdCBiaWJsZSA9IGNyZWF0ZVN0b3J5QmlibGUoXHJcbiAgICAn5p2O55m95LygJyxcclxuICAgICfor5fku5nkvKDlpYcnLFxyXG4gICAgJ+S8oOiusCcsXHJcbiAgICAn5ZSQ5pydJyxcclxuICAgICfosarmlL7mtarmvKsnLFxyXG4gICAgJ+adjueZveS4gOeUn+eahOS8oOWlh+e7j+WOhicsXHJcbiAgICAxMFxyXG4gICk7XHJcbiAgY29uc3QgYmlibGVXaXRoQ2hhciA9IGFkZENoYXJhY3RlcihiaWJsZSwgJ+adjueZvScsICdwcm90YWdvbmlzdCcsIFsn6LGq5pS+JywgJ+a1qua8qyddLCBbJ+WGmeivlycsICfppa7phZInXSk7XHJcbiAgY29uc3Qgc3RhdGUgPSBjcmVhdGVTdG9yeVN0YXRlKGJpYmxlV2l0aENoYXIuaWQsIDEwKTtcclxuXHJcbiAgY29uc3QgcmV0cmlldmVyID0gY3JlYXRlTWVtb3J5UmV0cmlldmVyKHZlY3RvclN0b3JlKTtcclxuICBjb25zdCByZXRyaWV2ZWQgPSBhd2FpdCByZXRyaWV2ZXIucmV0cmlldmVGb3JDaGFwdGVyKHtcclxuICAgIGJpYmxlOiBiaWJsZVdpdGhDaGFyLFxyXG4gICAgc3RhdGUsXHJcbiAgICBjdXJyZW50Q2hhcHRlcjogMyxcclxuICB9LCAzKTtcclxuXHJcbiAgY29uc29sZS5sb2coYOKchSBSZXRyaWV2ZWQgJHtyZXRyaWV2ZWQubGVuZ3RofSByZWxldmFudCBtZW1vcmllc2ApO1xyXG4gIHJldHJpZXZlZC5mb3JFYWNoKChyLCBpKSA9PiB7XHJcbiAgICBjb25zb2xlLmxvZyhgICAke2kgKyAxfS4gWyR7ci5tZW1vcnkuY2F0ZWdvcnl9XSAke3IubWVtb3J5LmNvbnRlbnQuc3Vic3RyaW5nKDAsIDUwKX0uLi5gKTtcclxuICB9KTtcclxuXHJcbiAgLy8gVGVzdCA2OiBGb3JtYXQgZm9yIFByb21wdFxyXG4gIGNvbnNvbGUubG9nKCdcXG5UZXN0IDY6IEZvcm1hdCBNZW1vcmllcyBmb3IgUHJvbXB0Jyk7XHJcbiAgY29uc3QgZm9ybWF0dGVkID0gcmV0cmlldmVyLmZvcm1hdE1lbW9yaWVzRm9yUHJvbXB0KHJldHJpZXZlZCk7XHJcbiAgY29uc29sZS5sb2coJ0Zvcm1hdHRlZCBvdXRwdXQ6Jyk7XHJcbiAgY29uc29sZS5sb2coZm9ybWF0dGVkKTtcclxuXHJcbiAgLy8gVGVzdCA3OiBTZXJpYWxpemF0aW9uXHJcbiAgY29uc29sZS5sb2coJ1xcblRlc3QgNzogVmVjdG9yIFN0b3JlIFNlcmlhbGl6YXRpb24nKTtcclxuICBjb25zdCBzZXJpYWxpemVkID0gdmVjdG9yU3RvcmUuc2VyaWFsaXplKCk7XHJcbiAgY29uc3QgcGFyc2VkID0gSlNPTi5wYXJzZShzZXJpYWxpemVkKTtcclxuICBjb25zb2xlLmxvZyhg4pyFIFNlcmlhbGl6ZWQgc3RvcmUgd2l0aCAke3BhcnNlZC5tZW1vcmllcy5sZW5ndGh9IG1lbW9yaWVzYCk7XHJcblxyXG4gIC8vIFRlc3QgODogTWVtb3J5IEV4dHJhY3Rpb24gKHJlcXVpcmVzIExMTSlcclxuICBjb25zb2xlLmxvZygnXFxuVGVzdCA4OiBNZW1vcnkgRXh0cmFjdGlvbiBmcm9tIENoYXB0ZXInKTtcclxuICBjb25zdCB0ZXN0Q2hhcHRlciA9IHtcclxuICAgIGlkOiAnY2gtMycsXHJcbiAgICBzdG9yeUlkOiBiaWJsZS5pZCxcclxuICAgIG51bWJlcjogMyxcclxuICAgIHRpdGxlOiAn5pyI5LiL54us6YWMJyxcclxuICAgIGNvbnRlbnQ6IGBcclxu6Iqx6Ze05LiA5aO26YWS77yM54us6YWM5peg55u45Lqy44CCXHJcbuS4vuadr+mCgOaYjuaciO+8jOWvueW9seaIkOS4ieS6uuOAglxyXG7mnIjml6LkuI3op6Pppa7vvIzlvbHlvpLpmo/miJHouqvjgIJcclxu5pqC5Ly05pyI5bCG5b2x77yM6KGM5LmQ6aG75Y+K5pil44CCXHJcbuaIkeatjOaciOW+mOW+iu+8jOaIkeiInuW9sembtuS5seOAglxyXG7phpLml7blkIzkuqTmrKLvvIzphonlkI7lkITliIbmlaPjgIJcclxu5rC457uT5peg5oOF5ri477yM55u45pyf6YKI5LqR5rGJ44CCXHJcblxyXG7mnY7nmb3ni6zoh6rlnKjoirHlm63kuK3ppa7phZLvvIzmsqHmnInkurLlj4vpmarkvLTjgILku5bkuL7otbfphZLmna/pgoDor7fmmI7mnIjlhbHppa7vvIxcclxu5Yqg5LiK6Ieq5bex55qE5b2x5a2Q77yM5Lu/5L2b5oiQ5LqG5LiJ5Liq5Lq644CC5pyI5Lqu5LiN5oeC6aWu6YWS77yM5b2x5a2Q5Lmf5Y+q5piv6Lef6ZqP77yMXHJcbuS9huadjueZveS+neeEtuS4juWug+S7rOebuOS8tO+8jOS6q+WPl+i/meaYpeaXpeeahOasouS5kOOAguS7luWUseatjOaXtuaciOS6ruS8vOS5juWcqOW+mOW+iu+8jFxyXG7ot7PoiJ7ml7blvbHlrZDkuZ/pm7bkubHlnLDot5/pmo/jgILmuIXphpLml7bkuIDotbfmrKLkuZDvvIzphonphZLlkI7lkIToh6rliIbmlaPjgIJcclxu5p2O55m95biM5pyb5LiO5piO5pyI5ZKM5b2x5a2Q5rC46L+c57uT5LiL6L+Z5peg5oOF55qE5ri45Ly077yM55u457qm5Zyo6YGl6L+c55qE5LqR5rGJ5LmL6Ze044CCXHJcbmAsXHJcbiAgICBzdW1tYXJ5OiAn5p2O55m95pyI5LiL54us6YWM77yM5LiO5piO5pyI5ZKM5b2x5a2Q5Li65Ly077yM5YaZ5LiL5Y2D5Y+k5ZCN56+HJyxcclxuICAgIHdvcmRDb3VudDogMjAwLFxyXG4gICAgZ2VuZXJhdGVkQXQ6IG5ldyBEYXRlKCksXHJcbiAgfTtcclxuXHJcbiAgdHJ5IHtcclxuICAgIGNvbnN0IGV4dHJhY3RlZCA9IGF3YWl0IG1lbW9yeUV4dHJhY3Rvci5leHRyYWN0KHRlc3RDaGFwdGVyLCBiaWJsZVdpdGhDaGFyKTtcclxuICAgIGNvbnNvbGUubG9nKGDinIUgRXh0cmFjdGVkICR7ZXh0cmFjdGVkLmxlbmd0aH0gbWVtb3JpZXMgZnJvbSBjaGFwdGVyYCk7XHJcbiAgICBleHRyYWN0ZWQuZm9yRWFjaCgobSwgaSkgPT4ge1xyXG4gICAgICBjb25zb2xlLmxvZyhgICAke2kgKyAxfS4gWyR7bS5jYXRlZ29yeX1dICR7bS5jb250ZW50fWApO1xyXG4gICAgfSk7XHJcbiAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgIGNvbnNvbGUubG9nKCfimqDvuI8gTWVtb3J5IGV4dHJhY3Rpb24gc2tpcHBlZCAoTExNIG1heSBub3QgYmUgYXZhaWxhYmxlKScpO1xyXG4gIH1cclxuXHJcbiAgLy8gQ2xlYW51cFxyXG4gIGNsZWFyVmVjdG9yU3RvcmUoc3RvcnlJZCk7XHJcbiAgY29uc29sZS5sb2coJ1xcbuKchSBBbGwgVmVjdG9yIE1lbW9yeSB0ZXN0cyBwYXNzZWQhJyk7XHJcbn1cclxuXHJcbnRlc3RWZWN0b3JNZW1vcnkoKVxyXG4gIC50aGVuKCgpID0+IHtcclxuICAgIGNvbnNvbGUubG9nKCdcXG7wn46JIFBoYXNlIDMgKFZlY3RvciBNZW1vcnkpIHRlc3RzIGNvbXBsZXRlIScpO1xyXG4gICAgcHJvY2Vzcy5leGl0KDApO1xyXG4gIH0pXHJcbiAgLmNhdGNoKChlcnJvcikgPT4ge1xyXG4gICAgY29uc29sZS5lcnJvcignXFxu4p2MIFRlc3QgZmFpbGVkOicsIGVycm9yKTtcclxuICAgIHByb2Nlc3MuZXhpdCgxKTtcclxuICB9KTtcclxuIl19
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const index_js_1 = require("../index.js");
|
|
4
|
+
console.log('Testing World Simulation Layer (Phase 8)...\n');
|
|
5
|
+
// Setup test story
|
|
6
|
+
const bible = (0, index_js_1.createStoryBible)('江湖恩仇录', '武侠复仇与救赎', 'wuxia', '明朝江南', '悲壮苍凉', '少年侠客为父报仇,在江湖中经历恩怨情仇,最终领悟武道真谛', 10);
|
|
7
|
+
// Test 1: Create character agents
|
|
8
|
+
console.log('Test 1: Create Character Agents');
|
|
9
|
+
let testBible = (0, index_js_1.createStoryBible)('江湖恩仇录', '武侠复仇与救赎', 'wuxia', '明朝江南', '悲壮苍凉', '少年侠客为父报仇,在江湖中经历恩怨情仇,最终领悟武道真谛', 10);
|
|
10
|
+
testBible = (0, index_js_1.addCharacter)(testBible, '林云', 'protagonist', ['坚毅', '正直', '冲动'], ['为父报仇', '成为大侠']);
|
|
11
|
+
testBible = (0, index_js_1.addCharacter)(testBible, '血手人屠', 'antagonist', ['阴险', '残忍', '多疑'], ['巩固势力', '消灭威胁']);
|
|
12
|
+
const structuredState = (0, index_js_1.initializeCharactersFromBible)((0, index_js_1.createStructuredState)('test-story'), testBible);
|
|
13
|
+
const charNames = Object.keys(structuredState.characters);
|
|
14
|
+
console.log(` Characters in state: ${charNames.join(', ')}`);
|
|
15
|
+
const liBai = index_js_1.characterAgentSystem.createAgent(structuredState.characters[charNames[0]], ['坚毅', '正直', '冲动']);
|
|
16
|
+
console.log(` Created: ${liBai.name}`);
|
|
17
|
+
console.log(` Goals: ${liBai.goals.join(', ')}`);
|
|
18
|
+
console.log(` Personality: ${liBai.personality.join(', ')}`);
|
|
19
|
+
console.log('✅ Character agent created');
|
|
20
|
+
// Test 2: Manage agenda
|
|
21
|
+
console.log('\nTest 2: Manage Character Agenda');
|
|
22
|
+
let agentWithAgenda = index_js_1.characterAgentSystem.addAgendaItem(liBai, '寻找仇人线索', 9, 3);
|
|
23
|
+
agentWithAgenda = index_js_1.characterAgentSystem.addAgendaItem(agentWithAgenda, '提升武功', 7);
|
|
24
|
+
agentWithAgenda = index_js_1.characterAgentSystem.addAgendaItem(agentWithAgenda, '救助无辜', 5);
|
|
25
|
+
console.log(` Agenda items: ${agentWithAgenda.agenda.length}`);
|
|
26
|
+
console.log(` Top priority: ${agentWithAgenda.agenda.sort((a, b) => b.priority - a.priority)[0].action}`);
|
|
27
|
+
console.log('✅ Agenda management working');
|
|
28
|
+
// Test 3: Knowledge and relationships
|
|
29
|
+
console.log('\nTest 3: Knowledge and Relationships');
|
|
30
|
+
let knowledgeableAgent = index_js_1.characterAgentSystem.addKnowledge(agentWithAgenda, '仇人住在黑木崖');
|
|
31
|
+
knowledgeableAgent = index_js_1.characterAgentSystem.addKnowledge(knowledgeableAgent, '师父是隐世高手');
|
|
32
|
+
knowledgeableAgent = index_js_1.characterAgentSystem.updateRelationship(knowledgeableAgent, '师父', '尊敬');
|
|
33
|
+
knowledgeableAgent = index_js_1.characterAgentSystem.updateRelationship(knowledgeableAgent, '仇人', '仇恨');
|
|
34
|
+
console.log(` Knowledge: ${knowledgeableAgent.knowledge.length} facts`);
|
|
35
|
+
console.log(` Relationships: ${Object.keys(knowledgeableAgent.relationships).length}`);
|
|
36
|
+
console.log('✅ Knowledge and relationships tracked');
|
|
37
|
+
// Test 4: Simple decision making
|
|
38
|
+
console.log('\nTest 4: Simple Decision Making');
|
|
39
|
+
const villain = {
|
|
40
|
+
name: '仇人',
|
|
41
|
+
goals: ['巩固势力', '消灭威胁'],
|
|
42
|
+
currentGoal: '消灭威胁',
|
|
43
|
+
location: '黑木崖',
|
|
44
|
+
knowledge: ['主角在追查自己'],
|
|
45
|
+
relationships: { '主角': '敌对' },
|
|
46
|
+
personality: ['阴险', '残忍', '多疑'],
|
|
47
|
+
emotionalState: '警惕',
|
|
48
|
+
inventory: [],
|
|
49
|
+
agenda: [],
|
|
50
|
+
};
|
|
51
|
+
const context = {
|
|
52
|
+
character: knowledgeableAgent,
|
|
53
|
+
otherCharacters: [villain],
|
|
54
|
+
worldEvents: ['江湖传闻主角在寻找仇人'],
|
|
55
|
+
currentChapter: 2,
|
|
56
|
+
storyContext: '主角正在追查杀父仇人',
|
|
57
|
+
};
|
|
58
|
+
const decision = index_js_1.characterAgentSystem.getSimpleDecision(context);
|
|
59
|
+
console.log(` Decision: ${decision.action}`);
|
|
60
|
+
console.log(` Reasoning: ${decision.reasoning}`);
|
|
61
|
+
console.log(` Consequences: ${decision.consequences.length}`);
|
|
62
|
+
console.log('✅ Simple decision generated');
|
|
63
|
+
// Test 5: World State Manager
|
|
64
|
+
console.log('\nTest 5: World State Manager');
|
|
65
|
+
const world = (0, index_js_1.createWorldStateManager)('test-story');
|
|
66
|
+
world.initialize('江南小镇', [knowledgeableAgent, villain]);
|
|
67
|
+
console.log(` Locations: ${world.getState().locations.size}`);
|
|
68
|
+
console.log(` Characters: ${world.getState().characters.size}`);
|
|
69
|
+
console.log('✅ World state initialized');
|
|
70
|
+
// Test 6: Location management
|
|
71
|
+
console.log('\nTest 6: Location Management');
|
|
72
|
+
world.addLocation('loc-forest', '黑森林', '阴森茂密的森林,传说有强盗出没', ['loc-start']);
|
|
73
|
+
world.addLocation('loc-cliff', '黑木崖', '悬崖上的山寨,仇人老巢', ['loc-forest']);
|
|
74
|
+
world.connectLocations('loc-start', 'loc-forest');
|
|
75
|
+
console.log(` Total locations: ${world.getState().locations.size}`);
|
|
76
|
+
console.log('✅ Locations managed');
|
|
77
|
+
// Test 7: Character movement
|
|
78
|
+
console.log('\nTest 7: Character Movement');
|
|
79
|
+
const moved = world.moveCharacter('主角', 'loc-forest');
|
|
80
|
+
console.log(` Movement successful: ${moved}`);
|
|
81
|
+
const location = world.getCharacterLocation('主角');
|
|
82
|
+
console.log(` Now at: ${location?.name}`);
|
|
83
|
+
const charactersThere = world.getCharactersAtLocation('loc-forest');
|
|
84
|
+
console.log(` Characters in forest: ${charactersThere.map(c => c.name).join(', ')}`);
|
|
85
|
+
console.log('✅ Character movement working');
|
|
86
|
+
// Test 8: Event resolution
|
|
87
|
+
console.log('\nTest 8: Event Resolution');
|
|
88
|
+
const decisions = [
|
|
89
|
+
{
|
|
90
|
+
character: '主角',
|
|
91
|
+
action: '潜入黑木崖侦查',
|
|
92
|
+
target: '仇人',
|
|
93
|
+
reasoning: '需要了解敌人布置',
|
|
94
|
+
consequences: ['可能被发现', '获得情报'],
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
character: '仇人',
|
|
98
|
+
action: '设下埋伏等待主角',
|
|
99
|
+
target: '主角',
|
|
100
|
+
reasoning: '知道主角会来',
|
|
101
|
+
consequences: ['可能捕获主角', '暴露布置'],
|
|
102
|
+
},
|
|
103
|
+
];
|
|
104
|
+
const events = index_js_1.eventResolver.resolveDecisions(decisions, 2);
|
|
105
|
+
console.log(` Events generated: ${events.length}`);
|
|
106
|
+
for (const event of events) {
|
|
107
|
+
console.log(` - ${event.type}: ${event.description}`);
|
|
108
|
+
}
|
|
109
|
+
console.log('✅ Events resolved from decisions');
|
|
110
|
+
// Test 9: Process events
|
|
111
|
+
console.log('\nTest 9: Process Events');
|
|
112
|
+
const agents = new Map();
|
|
113
|
+
agents.set('主角', knowledgeableAgent);
|
|
114
|
+
agents.set('仇人', villain);
|
|
115
|
+
const resolutions = index_js_1.eventResolver.processEvents(events, agents);
|
|
116
|
+
console.log(` Resolutions: ${resolutions.length}`);
|
|
117
|
+
for (const res of resolutions) {
|
|
118
|
+
console.log(` - ${res.outcome}`);
|
|
119
|
+
console.log(` Consequences: ${res.consequences.join(', ')}`);
|
|
120
|
+
}
|
|
121
|
+
console.log('✅ Events processed');
|
|
122
|
+
// Test 10: World state summary
|
|
123
|
+
console.log('\nTest 10: World State Summary');
|
|
124
|
+
world.applyResolutions(resolutions);
|
|
125
|
+
world.advanceChapter();
|
|
126
|
+
const summary = world.getSummary();
|
|
127
|
+
console.log('--- World Summary ---');
|
|
128
|
+
console.log(summary);
|
|
129
|
+
console.log('✅ World summary generated');
|
|
130
|
+
// Test 11: Serialization
|
|
131
|
+
console.log('\nTest 11: Serialization');
|
|
132
|
+
const serialized = world.serialize();
|
|
133
|
+
const world2 = (0, index_js_1.createWorldStateManager)('test-story');
|
|
134
|
+
world2.load(serialized);
|
|
135
|
+
console.log(` Serialized and loaded successfully`);
|
|
136
|
+
console.log(` Loaded chapter: ${world2.getState().currentChapter}`);
|
|
137
|
+
console.log(` Loaded locations: ${world2.getState().locations.size}`);
|
|
138
|
+
console.log('✅ Serialization working');
|
|
139
|
+
// Test 12: Simulate turn (no LLM)
|
|
140
|
+
console.log('\nTest 12: Simulate Turn');
|
|
141
|
+
const allAgents = [knowledgeableAgent, villain];
|
|
142
|
+
index_js_1.characterAgentSystem.simulateTurn(allAgents, ['主角进入黑森林', '仇人收到密报'], 3, '主角接近仇人老巢', false // no LLM
|
|
143
|
+
).then(decisions => {
|
|
144
|
+
console.log(` Decisions made: ${decisions.length}`);
|
|
145
|
+
for (const d of decisions) {
|
|
146
|
+
console.log(` - ${d.character}: ${d.action}`);
|
|
147
|
+
}
|
|
148
|
+
console.log('✅ Turn simulation complete');
|
|
149
|
+
console.log('\n✅ All World Simulation tests passed!');
|
|
150
|
+
console.log('\n🎉 Phase 8 (World Simulation Layer) tests complete!');
|
|
151
|
+
});
|
|
152
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ybGQtc2ltdWxhdGlvbi50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3Qvd29ybGQtc2ltdWxhdGlvbi50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsMENBVXFCO0FBRXJCLE9BQU8sQ0FBQyxHQUFHLENBQUMsK0NBQStDLENBQUMsQ0FBQztBQUU3RCxtQkFBbUI7QUFDbkIsTUFBTSxLQUFLLEdBQUcsSUFBQSwyQkFBZ0IsRUFDNUIsT0FBTyxFQUNQLFNBQVMsRUFDVCxPQUFPLEVBQ1AsTUFBTSxFQUNOLE1BQU0sRUFDTiw4QkFBOEIsRUFDOUIsRUFBRSxDQUNILENBQUM7QUFFRixrQ0FBa0M7QUFDbEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO0FBQy9DLElBQUksU0FBUyxHQUFHLElBQUEsMkJBQWdCLEVBQzlCLE9BQU8sRUFDUCxTQUFTLEVBQ1QsT0FBTyxFQUNQLE1BQU0sRUFDTixNQUFNLEVBQ04sOEJBQThCLEVBQzlCLEVBQUUsQ0FDSCxDQUFDO0FBQ0YsU0FBUyxHQUFHLElBQUEsdUJBQVksRUFBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztBQUMvRixTQUFTLEdBQUcsSUFBQSx1QkFBWSxFQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO0FBRWhHLE1BQU0sZUFBZSxHQUFHLElBQUEsd0NBQTZCLEVBQ25ELElBQUEsZ0NBQXFCLEVBQUMsWUFBWSxDQUFDLEVBQ25DLFNBQVMsQ0FDVixDQUFDO0FBRUYsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxl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QixDQUFDLENBQUM7SUFFMUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO0lBQ3RELE9BQU8sQ0FBQyxHQUFHLENBQUMsdURBQXVELENBQUMsQ0FBQztBQUN2RSxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgY2hhcmFjdGVyQWdlbnRTeXN0ZW0sXHJcbiAgZXZlbnRSZXNvbHZlcixcclxuICBjcmVhdGVXb3JsZFN0YXRlTWFuYWdlcixcclxuICBjcmVhdGVTdHJ1Y3R1cmVkU3RhdGUsXHJcbiAgaW5pdGlhbGl6ZUNoYXJhY3RlcnNGcm9tQmlibGUsXHJcbiAgY3JlYXRlU3RvcnlCaWJsZSxcclxuICBhZGRDaGFyYWN0ZXIsXHJcbiAgdHlwZSBDaGFyYWN0ZXJBZ2VudCxcclxuICB0eXBlIENoYXJhY3RlckRlY2lzaW9uLFxyXG59IGZyb20gJy4uL2luZGV4LmpzJztcclxuXHJcbmNvbnNvbGUubG9nKCdUZXN0aW5nIFdvcmxkIFNpbXVsYXRpb24gTGF5ZXIgKFBoYXNlIDgpLi4uXFxuJyk7XHJcblxyXG4vLyBTZXR1cCB0ZXN0IHN0b3J5XHJcbmNvbnN0IGJpYmxlID0gY3JlYXRlU3RvcnlCaWJsZShcclxuICAn5rGf5rmW5oGp5LuH5b2VJyxcclxuICAn5q2m5L6g5aSN5LuH5LiO5pWR6LWOJyxcclxuICAnd3V4aWEnLFxyXG4gICfmmI7mnJ3msZ/ljZcnLFxyXG4gICfmgrLlo67oi43lh4knLFxyXG4gICflsJHlubTkvqDlrqLkuLrniLbmiqXku4fvvIzlnKjmsZ/muZbkuK3nu4/ljobmganmgKjmg4Xku4fvvIzmnIDnu4jpoobmgp/mrabpgZPnnJ/osJsnLFxyXG4gIDEwXHJcbik7XHJcblxyXG4vLyBUZXN0IDE6IENyZWF0ZSBjaGFyYWN0ZXIgYWdlbnRzXHJcbmNvbnNvbGUubG9nKCdUZXN0IDE6IENyZWF0ZSBDaGFyYWN0ZXIgQWdlbnRzJyk7XHJcbmxldCB0ZXN0QmlibGUgPSBjcmVhdGVTdG9yeUJpYmxlKFxyXG4gICfmsZ/muZbmganku4flvZUnLFxyXG4gICfmrabkvqDlpI3ku4fkuI7mlZHotY4nLFxyXG4gICd3dXhpYScsXHJcbiAgJ+aYjuacneaxn+WNlycsXHJcbiAgJ+aCsuWjruiLjeWHiScsXHJcbiAgJ+WwkeW5tOS+oOWuouS4uueItuaKpeS7h++8jOWcqOaxn+a5luS4ree7j+WOhuaBqeaAqOaDheS7h++8jOacgOe7iOmihuaCn+atpumBk+ecn+iwmycsXHJcbiAgMTBcclxuKTtcclxudGVzdEJpYmxlID0gYWRkQ2hhcmFjdGVyKHRlc3RCaWJsZSwgJ+ael+S6kScsICdwcm90YWdvbmlzdCcsIFsn5Z2a5q+FJywgJ+ato+ebtCcsICflhrLliqgnXSwgWyfkuLrniLbmiqXku4cnLCAn5oiQ5Li65aSn5L6gJ10pO1xyXG50ZXN0QmlibGUgPSBhZGRDaGFyYWN0ZXIodGVzdEJpYmxlLCAn6KGA5omL5Lq65bGgJywgJ2FudGFnb25pc3QnLCBbJ+mYtOmZqScsICfmrovlv40nLCAn5aSa55aRJ10sIFsn5bep5Zu65Yq/5YqbJywgJ+a2iOeBreWogeiDgSddKTtcclxuXHJcbmNvbnN0IHN0cnVjdHVyZWRTdGF0ZSA9IGluaXRpYWxpemVDaGFyYWN0ZXJzRnJvbUJpYmxlKFxyXG4gIGNyZWF0ZVN0cnVjdHVyZWRTdGF0ZSgndGVzdC1zdG9yeScpLFxyXG4gIHRlc3RCaWJsZVxyXG4pO1xyXG5cclxuY29uc3QgY2hhck5hbWVzID0gT2JqZWN0LmtleXMoc3RydWN0dXJlZFN0YXRlLmNoYXJhY3RlcnMpO1xyXG5jb25zb2xlLmxvZyhgICBDaGFyYWN0ZXJzIGluIHN0YXRlOiAke2NoYXJOYW1lcy5qb2luKCcsICcpfWApO1xyXG5cclxuY29uc3QgbGlCYWkgPSBjaGFyYWN0ZXJBZ2VudFN5c3RlbS5jcmVhdGVBZ2VudChcclxuICBzdHJ1Y3R1cmVkU3RhdGUuY2hhcmFjdGVyc1tjaGFyTmFtZXNbMF1dLFxyXG4gIFsn5Z2a5q+FJywgJ+ato+ebtCcsICflhrLliqgnXVxyXG4pO1xyXG5jb25zb2xlLmxvZyhgICBDcmVhdGVkOiAke2xpQmFpLm5hbWV9YCk7XHJcbmNvbnNvbGUubG9nKGAgIEdvYWxzOiAke2xpQmFpLmdvYWxzLmpvaW4oJywgJyl9YCk7XHJcbmNvbnNvbGUubG9nKGAgIFBlcnNvbmFsaXR5OiAke2xpQmFpLnBlcnNvbmFsaXR5LmpvaW4oJywgJyl9YCk7XHJcbmNvbnNvbGUubG9nKCfinIUgQ2hhcmFjdGVyIGFnZW50IGNyZWF0ZWQnKTtcclxuXHJcbi8vIFRlc3QgMjogTWFuYWdlIGFnZW5kYVxyXG5jb25zb2xlLmxvZygnXFxuVGVzdCAyOiBNYW5hZ2UgQ2hhcmFjdGVyIEFnZW5kYScpO1xyXG5sZXQgYWdlbnRXaXRoQWdlbmRhID0gY2hhcmFjdGVyQWdlbnRTeXN0ZW0uYWRkQWdlbmRhSXRlbShsaUJhaSwgJ+Wvu+aJvuS7h+S6uue6v+e0oicsIDksIDMpO1xyXG5hZ2VudFdpdGhBZ2VuZGEgPSBjaGFyYWN0ZXJBZ2VudFN5c3RlbS5hZGRBZ2VuZGFJdGVtKGFnZW50V2l0aEFnZW5kYSwgJ+aPkOWNh+atpuWKnycsIDcpO1xyXG5hZ2VudFdpdGhBZ2VuZGEgPSBjaGFyYWN0ZXJBZ2VudFN5c3RlbS5hZGRBZ2VuZGFJdGVtKGFnZW50V2l0aEFnZW5kYSwgJ+aVkeWKqeaXoOi+nCcsIDUpO1xyXG5jb25zb2xlLmxvZyhgICBBZ2VuZGEgaXRlbXM6ICR7YWdlbnRXaXRoQWdlbmRhLmFnZW5kYS5sZW5ndGh9YCk7XHJcbmNvbnNvbGUubG9nKGAgIFRvcCBwcmlvcml0eTogJHthZ2VudFdpdGhBZ2VuZGEuYWdlbmRhLnNvcnQoKGEsIGIpID0+IGIucHJpb3JpdHkgLSBhLnByaW9yaXR5KVswXS5hY3Rpb259YCk7XHJcbmNvbnNvbGUubG9nKCfinIUgQWdlbmRhIG1hbmFnZW1lbnQgd29ya2luZycpO1xyXG5cclxuLy8gVGVzdCAzOiBLbm93bGVkZ2UgYW5kIHJlbGF0aW9uc2hpcHNcclxuY29uc29sZS5sb2coJ1xcblRlc3QgMzogS25vd2xlZGdlIGFuZCBSZWxhdGlvbnNoaXBzJyk7XHJcbmxldCBrbm93bGVkZ2VhYmxlQWdlbnQgPSBjaGFyYWN0ZXJBZ2VudFN5c3RlbS5hZGRLbm93bGVkZ2UoYWdlbnRXaXRoQWdlbmRhLCAn5LuH5Lq65L2P5Zyo6buR5pyo5bSWJyk7XHJcbmtub3dsZWRnZWFibGVBZ2VudCA9IGNoYXJhY3RlckFnZW50U3lzdGVtLmFkZEtub3dsZWRnZShrbm93bGVkZ2VhYmxlQWdlbnQsICfluIjniLbmmK/pmpDkuJbpq5jmiYsnKTtcclxua25vd2xlZGdlYWJsZUFnZW50ID0gY2hhcmFjdGVyQWdlbnRTeXN0ZW0udXBkYXRlUmVsYXRpb25zaGlwKGtub3dsZWRnZWFibGVBZ2VudCwgJ+W4iOeIticsICflsIrmlawnKTtcclxua25vd2xlZGdlYWJsZUFnZW50ID0gY2hhcmFjdGVyQWdlbnRTeXN0ZW0udXBkYXRlUmVsYXRpb25zaGlwKGtub3dsZWRnZWFibGVBZ2VudCwgJ+S7h+S6uicsICfku4fmgagnKTtcclxuY29uc29sZS5sb2coYCAgS25vd2xlZGdlOiAke2tub3dsZWRnZWFibGVBZ2VudC5rbm93bGVkZ2UubGVuZ3RofSBmYWN0c2ApO1xyXG5jb25zb2xlLmxvZyhgICBSZWxhdGlvbnNoaXBzOiAke09iamVjdC5rZXlzKGtub3dsZWRnZWFibGVBZ2VudC5yZWxhdGlvbnNoaXBzKS5sZW5ndGh9YCk7XHJcbmNvbnNvbGUubG9nKCfinIUgS25vd2xlZGdlIGFuZCByZWxhdGlvbnNoaXBzIHRyYWNrZWQnKTtcclxuXHJcbi8vIFRlc3QgNDogU2ltcGxlIGRlY2lzaW9uIG1ha2luZ1xyXG5jb25zb2xlLmxvZygnXFxuVGVzdCA0OiBTaW1wbGUgRGVjaXNpb24gTWFraW5nJyk7XHJcbmNvbnN0IHZpbGxhaW46IENoYXJhY3RlckFnZW50ID0ge1xyXG4gIG5hbWU6ICfku4fkuronLFxyXG4gIGdvYWxzOiBbJ+W3qeWbuuWKv+WKmycsICfmtojnga3lqIHog4EnXSxcclxuICBjdXJyZW50R29hbDogJ+a2iOeBreWogeiDgScsXHJcbiAgbG9jYXRpb246ICfpu5HmnKjltJYnLFxyXG4gIGtub3dsZWRnZTogWyfkuLvop5LlnKjov73mn6Xoh6rlt7EnXSxcclxuICByZWxhdGlvbnNoaXBzOiB7ICfkuLvop5InOiAn5pWM5a+5JyB9LFxyXG4gIHBlcnNvbmFsaXR5OiBbJ+mYtOmZqScsICfmrovlv40nLCAn5aSa55aRJ10sXHJcbiAgZW1vdGlvbmFsU3RhdGU6ICforabmg5UnLFxyXG4gIGludmVudG9yeTogW10sXHJcbiAgYWdlbmRhOiBbXSxcclxufTtcclxuXHJcbmNvbnN0IGNvbnRleHQgPSB7XHJcbiAgY2hhcmFjdGVyOiBrbm93bGVkZ2VhYmxlQWdlbnQsXHJcbiAgb3RoZXJDaGFyYWN0ZXJzOiBbdmlsbGFpbl0sXHJcbiAgd29ybGRFdmVudHM6IFsn5rGf5rmW5Lyg6Ze75Li76KeS5Zyo5a+75om+5LuH5Lq6J10sXHJcbiAgY3VycmVudENoYXB0ZXI6IDIsXHJcbiAgc3RvcnlDb250ZXh0OiAn5Li76KeS5q2j5Zyo6L+95p+l5p2A54i25LuH5Lq6JyxcclxufTtcclxuXHJcbmNvbnN0IGRlY2lzaW9uID0gY2hhcmFjdGVyQWdlbnRTeXN0ZW0uZ2V0U2ltcGxlRGVjaXNpb24oY29udGV4dCk7XHJcbmNvbnNvbGUubG9nKGAgIERlY2lzaW9uOiAke2RlY2lzaW9uLmFjdGlvbn1gKTtcclxuY29uc29sZS5sb2coYCAgUmVhc29uaW5nOiAke2RlY2lzaW9uLnJlYXNvbmluZ31gKTtcclxuY29uc29sZS5sb2coYCAgQ29uc2VxdWVuY2VzOiAke2RlY2lzaW9uLmNvbnNlcXVlbmNlcy5sZW5ndGh9YCk7XHJcbmNvbnNvbGUubG9nKCfinIUgU2ltcGxlIGRlY2lzaW9uIGdlbmVyYXRlZCcpO1xyXG5cclxuLy8gVGVzdCA1OiBXb3JsZCBTdGF0ZSBNYW5hZ2VyXHJcbmNvbnNvbGUubG9nKCdcXG5UZXN0IDU6IFdvcmxkIFN0YXRlIE1hbmFnZXInKTtcclxuY29uc3Qgd29ybGQgPSBjcmVhdGVXb3JsZFN0YXRlTWFuYWdlcigndGVzdC1zdG9yeScpO1xyXG53b3JsZC5pbml0aWFsaXplKCfmsZ/ljZflsI/plYcnLCBba25vd2xlZGdlYWJsZUFnZW50LCB2aWxsYWluXSk7XHJcbmNvbnNvbGUubG9nKGAgIExvY2F0aW9uczogJHt3b3JsZC5nZXRTdGF0ZSgpLmxvY2F0aW9ucy5zaXplfWApO1xyXG5jb25zb2xlLmxvZyhgICBDaGFyYWN0ZXJzOiAke3dvcmxkLmdldFN0YXRlKCkuY2hhcmFjdGVycy5zaXplfWApO1xyXG5jb25zb2xlLmxvZygn4pyFIFdvcmxkIHN0YXRlIGluaXRpYWxpemVkJyk7XHJcblxyXG4vLyBUZXN0IDY6IExvY2F0aW9uIG1hbmFnZW1lbnRcclxuY29uc29sZS5sb2coJ1xcblRlc3QgNjogTG9jYXRpb24gTWFuYWdlbWVudCcpO1xyXG53b3JsZC5hZGRMb2NhdGlvbignbG9jLWZvcmVzdCcsICfpu5Hmo67mnpcnLCAn6Zi05qOu6IyC5a+G55qE5qOu5p6X77yM5Lyg6K+05pyJ5by655uX5Ye65rKhJywgWydsb2Mtc3RhcnQnXSk7XHJcbndvcmxkLmFkZExvY2F0aW9uKCdsb2MtY2xpZmYnLCAn6buR5pyo5bSWJywgJ+aCrOW0luS4iueahOWxseWvqO+8jOS7h+S6uuiAgeW3oicsIFsnbG9jLWZvcmVzdCddKTtcclxud29ybGQuY29ubmVjdExvY2F0aW9ucygnbG9jLXN0YXJ0JywgJ2xvYy1mb3Jlc3QnKTtcclxuY29uc29sZS5sb2coYCAgVG90YWwgbG9jYXRpb25zOiAke3dvcmxkLmdldFN0YXRlKCkubG9jYXRpb25zLnNpemV9YCk7XHJcbmNvbnNvbGUubG9nKCfinIUgTG9jYXRpb25zIG1hbmFnZWQnKTtcclxuXHJcbi8vIFRlc3QgNzogQ2hhcmFjdGVyIG1vdmVtZW50XHJcbmNvbnNvbGUubG9nKCdcXG5UZXN0IDc6IENoYXJhY3RlciBNb3ZlbWVudCcpO1xyXG5jb25zdCBtb3ZlZCA9IHdvcmxkLm1vdmVDaGFyYWN0ZXIoJ+S4u+inkicsICdsb2MtZm9yZXN0Jyk7XHJcbmNvbnNvbGUubG9nKGAgIE1vdmVtZW50IHN1Y2Nlc3NmdWw6ICR7bW92ZWR9YCk7XHJcbmNvbnN0IGxvY2F0aW9uID0gd29ybGQuZ2V0Q2hhcmFjdGVyTG9jYXRpb24oJ+S4u+inkicpO1xyXG5jb25zb2xlLmxvZyhgICBOb3cgYXQ6ICR7bG9jYXRpb24/Lm5hbWV9YCk7XHJcbmNvbnN0IGNoYXJhY3RlcnNUaGVyZSA9IHdvcmxkLmdldENoYXJhY3RlcnNBdExvY2F0aW9uKCdsb2MtZm9yZXN0Jyk7XHJcbmNvbnNvbGUubG9nKGAgIENoYXJhY3RlcnMgaW4gZm9yZXN0OiAke2NoYXJhY3RlcnNUaGVyZS5tYXAoYyA9PiBjLm5hbWUpLmpvaW4oJywgJyl9YCk7XHJcbmNvbnNvbGUubG9nKCfinIUgQ2hhcmFjdGVyIG1vdmVtZW50IHdvcmtpbmcnKTtcclxuXHJcbi8vIFRlc3QgODogRXZlbnQgcmVzb2x1dGlvblxyXG5jb25zb2xlLmxvZygnXFxuVGVzdCA4OiBFdmVudCBSZXNvbHV0aW9uJyk7XHJcbmNvbnN0IGRlY2lzaW9uczogQ2hhcmFjdGVyRGVjaXNpb25bXSA9IFtcclxuICB7XHJcbiAgICBjaGFyYWN0ZXI6ICfkuLvop5InLFxyXG4gICAgYWN0aW9uOiAn5r2c5YWl6buR5pyo5bSW5L6m5p+lJyxcclxuICAgIHRhcmdldDogJ+S7h+S6uicsXHJcbiAgICByZWFzb25pbmc6ICfpnIDopoHkuobop6PmlYzkurrluIPnva4nLFxyXG4gICAgY29uc2VxdWVuY2VzOiBbJ+WPr+iDveiiq+WPkeeOsCcsICfojrflvpfmg4XmiqUnXSxcclxuICB9LFxyXG4gIHtcclxuICAgIGNoYXJhY3RlcjogJ+S7h+S6uicsXHJcbiAgICBhY3Rpb246ICforr7kuIvln4vkvI/nrYnlvoXkuLvop5InLFxyXG4gICAgdGFyZ2V0OiAn5Li76KeSJyxcclxuICAgIHJlYXNvbmluZzogJ+efpemBk+S4u+inkuS8muadpScsXHJcbiAgICBjb25zZXF1ZW5jZXM6IFsn5Y+v6IO95o2V6I635Li76KeSJywgJ+aatOmcsuW4g+e9riddLFxyXG4gIH0sXHJcbl07XHJcblxyXG5jb25zdCBldmVudHMgPSBldmVudFJlc29sdmVyLnJlc29sdmVEZWNpc2lvbnMoZGVjaXNpb25zLCAyKTtcclxuY29uc29sZS5sb2coYCAgRXZlbnRzIGdlbmVyYXRlZDogJHtldmVudHMubGVuZ3RofWApO1xyXG5mb3IgKGNvbnN0IGV2ZW50IG9mIGV2ZW50cykge1xyXG4gIGNvbnNvbGUubG9nKGAgICAgLSAke2V2ZW50LnR5cGV9OiAke2V2ZW50LmRlc2NyaXB0aW9ufWApO1xyXG59XHJcbmNvbnNvbGUubG9nKCfinIUgRXZlbnRzIHJlc29sdmVkIGZyb20gZGVjaXNpb25zJyk7XHJcblxyXG4vLyBUZXN0IDk6IFByb2Nlc3MgZXZlbnRzXHJcbmNvbnNvbGUubG9nKCdcXG5UZXN0IDk6IFByb2Nlc3MgRXZlbnRzJyk7XHJcbmNvbnN0IGFnZW50cyA9IG5ldyBNYXA8c3RyaW5nLCBDaGFyYWN0ZXJBZ2VudD4oKTtcclxuYWdlbnRzLnNldCgn5Li76KeSJywga25vd2xlZGdlYWJsZUFnZW50KTtcclxuYWdlbnRzLnNldCgn5LuH5Lq6JywgdmlsbGFpbik7XHJcblxyXG5jb25zdCByZXNvbHV0aW9ucyA9IGV2ZW50UmVzb2x2ZXIucHJvY2Vzc0V2ZW50cyhldmVudHMsIGFnZW50cyk7XHJcbmNvbnNvbGUubG9nKGAgIFJlc29sdXRpb25zOiAke3Jlc29sdXRpb25zLmxlbmd0aH1gKTtcclxuZm9yIChjb25zdCByZXMgb2YgcmVzb2x1dGlvbnMpIHtcclxuICBjb25zb2xlLmxvZyhgICAgIC0gJHtyZXMub3V0Y29tZX1gKTtcclxuICBjb25zb2xlLmxvZyhgICAgICAgQ29uc2VxdWVuY2VzOiAke3Jlcy5jb25zZXF1ZW5jZXMuam9pbignLCAnKX1gKTtcclxufVxyXG5jb25zb2xlLmxvZygn4pyFIEV2ZW50cyBwcm9jZXNzZWQnKTtcclxuXHJcbi8vIFRlc3QgMTA6IFdvcmxkIHN0YXRlIHN1bW1hcnlcclxuY29uc29sZS5sb2coJ1xcblRlc3QgMTA6IFdvcmxkIFN0YXRlIFN1bW1hcnknKTtcclxud29ybGQuYXBwbHlSZXNvbHV0aW9ucyhyZXNvbHV0aW9ucyk7XHJcbndvcmxkLmFkdmFuY2VDaGFwdGVyKCk7XHJcbmNvbnN0IHN1bW1hcnkgPSB3b3JsZC5nZXRTdW1tYXJ5KCk7XHJcbmNvbnNvbGUubG9nKCctLS0gV29ybGQgU3VtbWFyeSAtLS0nKTtcclxuY29uc29sZS5sb2coc3VtbWFyeSk7XHJcbmNvbnNvbGUubG9nKCfinIUgV29ybGQgc3VtbWFyeSBnZW5lcmF0ZWQnKTtcclxuXHJcbi8vIFRlc3QgMTE6IFNlcmlhbGl6YXRpb25cclxuY29uc29sZS5sb2coJ1xcblRlc3QgMTE6IFNlcmlhbGl6YXRpb24nKTtcclxuY29uc3Qgc2VyaWFsaXplZCA9IHdvcmxkLnNlcmlhbGl6ZSgpO1xyXG5jb25zdCB3b3JsZDIgPSBjcmVhdGVXb3JsZFN0YXRlTWFuYWdlcigndGVzdC1zdG9yeScpO1xyXG53b3JsZDIubG9hZChzZXJpYWxpemVkKTtcclxuY29uc29sZS5sb2coYCAgU2VyaWFsaXplZCBhbmQgbG9hZGVkIHN1Y2Nlc3NmdWxseWApO1xyXG5jb25zb2xlLmxvZyhgICBMb2FkZWQgY2hhcHRlcjogJHt3b3JsZDIuZ2V0U3RhdGUoKS5jdXJyZW50Q2hhcHRlcn1gKTtcclxuY29uc29sZS5sb2coYCAgTG9hZGVkIGxvY2F0aW9uczogJHt3b3JsZDIuZ2V0U3RhdGUoKS5sb2NhdGlvbnMuc2l6ZX1gKTtcclxuY29uc29sZS5sb2coJ+KchSBTZXJpYWxpemF0aW9uIHdvcmtpbmcnKTtcclxuXHJcbi8vIFRlc3QgMTI6IFNpbXVsYXRlIHR1cm4gKG5vIExMTSlcclxuY29uc29sZS5sb2coJ1xcblRlc3QgMTI6IFNpbXVsYXRlIFR1cm4nKTtcclxuY29uc3QgYWxsQWdlbnRzID0gW2tub3dsZWRnZWFibGVBZ2VudCwgdmlsbGFpbl07XHJcbmNoYXJhY3RlckFnZW50U3lzdGVtLnNpbXVsYXRlVHVybihcclxuICBhbGxBZ2VudHMsXHJcbiAgWyfkuLvop5Lov5vlhaXpu5Hmo67mnpcnLCAn5LuH5Lq65pS25Yiw5a+G5oqlJ10sXHJcbiAgMyxcclxuICAn5Li76KeS5o6l6L+R5LuH5Lq66ICB5beiJyxcclxuICBmYWxzZSAvLyBubyBMTE1cclxuKS50aGVuKGRlY2lzaW9ucyA9PiB7XHJcbiAgY29uc29sZS5sb2coYCAgRGVjaXNpb25zIG1hZGU6ICR7ZGVjaXNpb25zLmxlbmd0aH1gKTtcclxuICBmb3IgKGNvbnN0IGQgb2YgZGVjaXNpb25zKSB7XHJcbiAgICBjb25zb2xlLmxvZyhgICAgIC0gJHtkLmNoYXJhY3Rlcn06ICR7ZC5hY3Rpb259YCk7XHJcbiAgfVxyXG4gIGNvbnNvbGUubG9nKCfinIUgVHVybiBzaW11bGF0aW9uIGNvbXBsZXRlJyk7XHJcblxyXG4gIGNvbnNvbGUubG9nKCdcXG7inIUgQWxsIFdvcmxkIFNpbXVsYXRpb24gdGVzdHMgcGFzc2VkIScpO1xyXG4gIGNvbnNvbGUubG9nKCdcXG7wn46JIFBoYXNlIDggKFdvcmxkIFNpbXVsYXRpb24gTGF5ZXIpIHRlc3RzIGNvbXBsZXRlIScpO1xyXG59KTtcclxuIl19
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export interface StoryBible {
|
|
2
|
+
id: string;
|
|
3
|
+
title: string;
|
|
4
|
+
theme: string;
|
|
5
|
+
genre: string;
|
|
6
|
+
setting: string;
|
|
7
|
+
tone: string;
|
|
8
|
+
targetChapters: number;
|
|
9
|
+
premise: string;
|
|
10
|
+
characters: CharacterProfile[];
|
|
11
|
+
plotThreads: PlotThread[];
|
|
12
|
+
createdAt: Date;
|
|
13
|
+
updatedAt: Date;
|
|
14
|
+
}
|
|
15
|
+
export interface CharacterProfile {
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
role: 'protagonist' | 'antagonist' | 'supporting';
|
|
19
|
+
personality: string[];
|
|
20
|
+
goals: string[];
|
|
21
|
+
background?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface PlotThread {
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
description: string;
|
|
27
|
+
status: 'dormant' | 'active' | 'escalating' | 'resolved';
|
|
28
|
+
tension: number;
|
|
29
|
+
}
|
|
30
|
+
export interface Chapter {
|
|
31
|
+
id: string;
|
|
32
|
+
storyId: string;
|
|
33
|
+
number: number;
|
|
34
|
+
title: string;
|
|
35
|
+
content: string;
|
|
36
|
+
summary: string;
|
|
37
|
+
wordCount: number;
|
|
38
|
+
generatedAt: Date;
|
|
39
|
+
}
|
|
40
|
+
export interface StoryState {
|
|
41
|
+
storyId: string;
|
|
42
|
+
currentChapter: number;
|
|
43
|
+
totalChapters: number;
|
|
44
|
+
currentTension: number;
|
|
45
|
+
activePlotThreads: string[];
|
|
46
|
+
chapterSummaries: ChapterSummary[];
|
|
47
|
+
}
|
|
48
|
+
export interface ChapterSummary {
|
|
49
|
+
chapterNumber: number;
|
|
50
|
+
summary: string;
|
|
51
|
+
keyEvents: string[];
|
|
52
|
+
characterChanges: Record<string, string>;
|
|
53
|
+
}
|
|
54
|
+
export interface GenerationContext {
|
|
55
|
+
bible: StoryBible;
|
|
56
|
+
state: StoryState;
|
|
57
|
+
chapterNumber: number;
|
|
58
|
+
targetWordCount?: number;
|
|
59
|
+
}
|
|
60
|
+
export interface WriterOutput {
|
|
61
|
+
content: string;
|
|
62
|
+
title: string;
|
|
63
|
+
wordCount: number;
|
|
64
|
+
}
|
|
65
|
+
export interface CompletenessResult {
|
|
66
|
+
isComplete: boolean;
|
|
67
|
+
reason?: string;
|
|
68
|
+
}
|
|
69
|
+
export interface LLMConfig {
|
|
70
|
+
model: string;
|
|
71
|
+
temperature: number;
|
|
72
|
+
maxTokens: number;
|
|
73
|
+
}
|
|
74
|
+
export interface LLMProviderConfig {
|
|
75
|
+
provider: 'openai' | 'deepseek' | string;
|
|
76
|
+
apiKey: string;
|
|
77
|
+
baseURL?: string;
|
|
78
|
+
model?: string;
|
|
79
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBpbnRlcmZhY2UgU3RvcnlCaWJsZSB7XHJcbiAgaWQ6IHN0cmluZztcclxuICB0aXRsZTogc3RyaW5nO1xyXG4gIHRoZW1lOiBzdHJpbmc7XHJcbiAgZ2VucmU6IHN0cmluZztcclxuICBzZXR0aW5nOiBzdHJpbmc7XHJcbiAgdG9uZTogc3RyaW5nO1xyXG4gIHRhcmdldENoYXB0ZXJzOiBudW1iZXI7XHJcbiAgcHJlbWlzZTogc3RyaW5nO1xyXG4gIGNoYXJhY3RlcnM6IENoYXJhY3RlclByb2ZpbGVbXTtcclxuICBwbG90VGhyZWFkczogUGxvdFRocmVhZFtdO1xyXG4gIGNyZWF0ZWRBdDogRGF0ZTtcclxuICB1cGRhdGVkQXQ6IERhdGU7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgQ2hhcmFjdGVyUHJvZmlsZSB7XHJcbiAgaWQ6IHN0cmluZztcclxuICBuYW1lOiBzdHJpbmc7XHJcbiAgcm9sZTogJ3Byb3RhZ29uaXN0JyB8ICdhbnRhZ29uaXN0JyB8ICdzdXBwb3J0aW5nJztcclxuICBwZXJzb25hbGl0eTogc3RyaW5nW107XHJcbiAgZ29hbHM6IHN0cmluZ1tdO1xyXG4gIGJhY2tncm91bmQ/OiBzdHJpbmc7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgUGxvdFRocmVhZCB7XHJcbiAgaWQ6IHN0cmluZztcclxuICBuYW1lOiBzdHJpbmc7XHJcbiAgZGVzY3JpcHRpb246IHN0cmluZztcclxuICBzdGF0dXM6ICdkb3JtYW50JyB8ICdhY3RpdmUnIHwgJ2VzY2FsYXRpbmcnIHwgJ3Jlc29sdmVkJztcclxuICB0ZW5zaW9uOiBudW1iZXI7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgQ2hhcHRlciB7XHJcbiAgaWQ6IHN0cmluZztcclxuICBzdG9yeUlkOiBzdHJpbmc7XHJcbiAgbnVtYmVyOiBudW1iZXI7XHJcbiAgdGl0bGU6IHN0cmluZztcclxuICBjb250ZW50OiBzdHJpbmc7XHJcbiAgc3VtbWFyeTogc3RyaW5nO1xyXG4gIHdvcmRDb3VudDogbnVtYmVyO1xyXG4gIGdlbmVyYXRlZEF0OiBEYXRlO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFN0b3J5U3RhdGUge1xyXG4gIHN0b3J5SWQ6IHN0cmluZztcclxuICBjdXJyZW50Q2hhcHRlcjogbnVtYmVyO1xyXG4gIHRvdGFsQ2hhcHRlcnM6IG51bWJlcjtcclxuICBjdXJyZW50VGVuc2lvbjogbnVtYmVyO1xyXG4gIGFjdGl2ZVBsb3RUaHJlYWRzOiBzdHJpbmdbXTtcclxuICBjaGFwdGVyU3VtbWFyaWVzOiBDaGFwdGVyU3VtbWFyeVtdO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIENoYXB0ZXJTdW1tYXJ5IHtcclxuICBjaGFwdGVyTnVtYmVyOiBudW1iZXI7XHJcbiAgc3VtbWFyeTogc3RyaW5nO1xyXG4gIGtleUV2ZW50czogc3RyaW5nW107XHJcbiAgY2hhcmFjdGVyQ2hhbmdlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBHZW5lcmF0aW9uQ29udGV4dCB7XHJcbiAgYmlibGU6IFN0b3J5QmlibGU7XHJcbiAgc3RhdGU6IFN0b3J5U3RhdGU7XHJcbiAgY2hhcHRlck51bWJlcjogbnVtYmVyO1xyXG4gIHRhcmdldFdvcmRDb3VudD86IG51bWJlcjtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBXcml0ZXJPdXRwdXQge1xyXG4gIGNvbnRlbnQ6IHN0cmluZztcclxuICB0aXRsZTogc3RyaW5nO1xyXG4gIHdvcmRDb3VudDogbnVtYmVyO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIENvbXBsZXRlbmVzc1Jlc3VsdCB7XHJcbiAgaXNDb21wbGV0ZTogYm9vbGVhbjtcclxuICByZWFzb24/OiBzdHJpbmc7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgTExNQ29uZmlnIHtcclxuICBtb2RlbDogc3RyaW5nO1xyXG4gIHRlbXBlcmF0dXJlOiBudW1iZXI7XHJcbiAgbWF4VG9rZW5zOiBudW1iZXI7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgTExNUHJvdmlkZXJDb25maWcge1xyXG4gIHByb3ZpZGVyOiAnb3BlbmFpJyB8ICdkZWVwc2VlaycgfCBzdHJpbmc7XHJcbiAgYXBpS2V5OiBzdHJpbmc7XHJcbiAgYmFzZVVSTD86IHN0cmluZztcclxuICBtb2RlbD86IHN0cmluZztcclxufVxyXG4iXX0=
|