briyah 1.0.8 → 1.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/README.md +109 -0
- package/dist/server/src/app/stripe.controller.js +3 -6
- package/dist/server/src/app/stripe.service.d.ts +2 -3
- package/dist/server/src/app/stripe.service.js +7 -9
- package/dist/server/src/app/transaction.service.d.ts +3 -3
- package/dist/server/src/app/transaction.service.js +11 -11
- package/dist/server/src/app.controller.js +8 -2
- package/dist/server/src/app.service.d.ts +5 -2
- package/dist/server/src/app.service.js +11 -2
- package/dist/server/src/sdk/index.d.ts +3 -1
- package/dist/server/src/sdk/index.js +3 -1
- package/dist/server/src/story/story-message.service.d.ts +4 -2
- package/dist/server/src/story/story-message.service.js +27 -8
- package/dist/server/src/story/story.service.js +4 -20
- package/dist/shared/types/app.types.d.ts +17 -12
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/Agent.html +13 -13
- package/docs/classes/Briyah.html +12 -12
- package/docs/classes/BriyahConfigService.html +5 -5
- package/docs/classes/Room.html +32 -32
- package/docs/classes/RoomMessage.html +41 -0
- package/docs/enums/MessageAction.html +3 -3
- package/docs/hierarchy.html +1 -1
- package/docs/index.html +16 -2
- package/docs/interfaces/AgentInfo.html +2 -2
- package/docs/interfaces/AgentMessagesResponse.html +2 -2
- package/docs/interfaces/AppService.html +220 -122
- package/docs/interfaces/Artifact.html +6 -0
- package/docs/interfaces/ArtifactMetadata.html +2 -2
- package/docs/interfaces/AttachDocumentResponse.html +2 -2
- package/docs/interfaces/BriyahConfigOptions.html +6 -6
- package/docs/interfaces/ChapterInfo.html +2 -2
- package/docs/interfaces/Character.html +2 -2
- package/docs/interfaces/CreateAgentResponse.html +2 -2
- package/docs/interfaces/CreateRoomResponse.html +2 -2
- package/docs/interfaces/CreateStoryResponse.html +2 -2
- package/docs/interfaces/FileList.html +2 -2
- package/docs/interfaces/LoggingOptions.html +5 -5
- package/docs/interfaces/Message.html +2 -2
- package/docs/interfaces/ModelInfo.html +2 -2
- package/docs/interfaces/PreparedPromptResponse.html +2 -2
- package/docs/interfaces/ProcessTextResponse.html +2 -2
- package/docs/interfaces/PromptFile.html +2 -2
- package/docs/interfaces/PromptFileContent.html +2 -2
- package/docs/interfaces/PromptFilesResponse.html +2 -2
- package/docs/interfaces/PromptFolder.html +2 -2
- package/docs/interfaces/PromptFoldersResponse.html +2 -2
- package/docs/interfaces/RoomDetails.html +2 -2
- package/docs/interfaces/RoomInfo.html +2 -2
- package/docs/interfaces/RoomMessagesResponse.html +2 -2
- package/docs/interfaces/StoryErrorEvent.html +12 -0
- package/docs/interfaces/StoryIdea.html +2 -2
- package/docs/interfaces/StoryInfo.html +2 -2
- package/docs/interfaces/StoryIntroduceCharacterEvent.html +12 -0
- package/docs/interfaces/StoryProgressChapterEvent.html +11 -0
- package/docs/interfaces/StoryState.html +8 -2
- package/docs/interfaces/StoryStateEvent.html +10 -0
- package/docs/interfaces/Transaction.html +10 -0
- package/docs/interfaces/TransactionHistoryResponse.html +3 -0
- package/docs/modules.html +1 -1
- package/docs/types/PromptScope.html +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -352,6 +352,115 @@ const messages = await appService.getRoomMessages(room.roomId);
|
|
|
352
352
|
console.log(`Messages: ${messages.messages.length}`);
|
|
353
353
|
```
|
|
354
354
|
|
|
355
|
+
### Example 6: Story Message Emitter
|
|
356
|
+
|
|
357
|
+
The story message emitter delivers real-time events during gameplay. Subscribe to it after creating the story but before the first player turn, so no events are missed.
|
|
358
|
+
|
|
359
|
+
```typescript
|
|
360
|
+
import type {
|
|
361
|
+
StoryStateEvent,
|
|
362
|
+
StoryIntroduceCharacterEvent,
|
|
363
|
+
StoryProgressChapterEvent,
|
|
364
|
+
StoryErrorEvent,
|
|
365
|
+
} from 'briyah';
|
|
366
|
+
|
|
367
|
+
const app = briyah.getAppService('user-123');
|
|
368
|
+
|
|
369
|
+
const story = await app.createStory(
|
|
370
|
+
'The Lost Kingdom',
|
|
371
|
+
'A medieval fantasy where ancient ruins hold a terrible secret',
|
|
372
|
+
'A disgraced knight seeking redemption'
|
|
373
|
+
);
|
|
374
|
+
|
|
375
|
+
const emitter = app.getStoryMessageEmitter(story.id);
|
|
376
|
+
|
|
377
|
+
// Fires after every turn with the full updated game state.
|
|
378
|
+
emitter.on('story-state', async (event: StoryStateEvent) => {
|
|
379
|
+
const { state } = event;
|
|
380
|
+
console.log('Latest message:', state.latestRoomMessage?.content);
|
|
381
|
+
|
|
382
|
+
// Detect the player's turn by comparing speaker names.
|
|
383
|
+
// Do NOT use state.humanPrompt for this — it is a UI display string,
|
|
384
|
+
// not a reliable turn indicator.
|
|
385
|
+
if (state.currentSpeaker === state.userAgentName) {
|
|
386
|
+
const input = await promptPlayer(state.humanPrompt);
|
|
387
|
+
await app.respondToStory(story.id, input);
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
// Fires when the narrator wants to introduce a new character.
|
|
392
|
+
// The host app should present this to the player before acting.
|
|
393
|
+
// Accept by calling introduceCharacterToStory, or decline with declineCharacter.
|
|
394
|
+
emitter.on('suggest-introduce-character', async (event: StoryIntroduceCharacterEvent) => {
|
|
395
|
+
const accept = await askPlayer(`Add ${event.characterName} to the story?`);
|
|
396
|
+
if (accept) {
|
|
397
|
+
await app.introduceCharacterToStory(story.id, event.characterName!, '', undefined, true);
|
|
398
|
+
} else {
|
|
399
|
+
await app.declineCharacter(story.id, event.characterName!);
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
// Fires when the narrator wants to advance to the next chapter.
|
|
404
|
+
// Call progressStory to accept. Ignoring the event stays in the current chapter —
|
|
405
|
+
// there is no explicit rejection call.
|
|
406
|
+
emitter.on('suggest-progress-chapter', async (_event: StoryProgressChapterEvent) => {
|
|
407
|
+
const accept = await askPlayer('The narrator suggests ending this chapter. Continue?');
|
|
408
|
+
if (accept) {
|
|
409
|
+
await app.progressStory(story.id);
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
// Fires on fatal errors during room processing.
|
|
414
|
+
// Named 'story-error' rather than 'error' to avoid Node.js throwing when no
|
|
415
|
+
// listener is attached.
|
|
416
|
+
emitter.on('story-error', (event: StoryErrorEvent) => {
|
|
417
|
+
if (event.errorType === 'InsufficientBalanceError') {
|
|
418
|
+
console.error('Out of credits:', event.message);
|
|
419
|
+
} else {
|
|
420
|
+
console.error(`Story error [${event.errorType}]:`, event.message);
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### Example 7: Recording Payments and Managing Balance
|
|
426
|
+
|
|
427
|
+
Briyah does not process payments itself — your application handles the payment provider interaction. Once a payment is confirmed, use `AppService` to record the transaction, credit the user's balance, and restart any stories that stalled due to insufficient funds.
|
|
428
|
+
|
|
429
|
+
```typescript
|
|
430
|
+
const app = briyah.getAppService(userId);
|
|
431
|
+
|
|
432
|
+
// --- When your payment provider initiates a charge ---
|
|
433
|
+
// Record it as pending so the transaction log stays consistent.
|
|
434
|
+
await app.recordTransaction(amount, paymentIntentId, 'pending');
|
|
435
|
+
|
|
436
|
+
// --- When your payment provider webhook confirms success ---
|
|
437
|
+
await app.updateTransactionStatus(paymentIntentId, 'succeeded');
|
|
438
|
+
await app.addBalance(amount);
|
|
439
|
+
|
|
440
|
+
// Resume any stories that paused mid-turn due to InsufficientBalanceError.
|
|
441
|
+
await app.resumePausedStories();
|
|
442
|
+
|
|
443
|
+
// --- When a payment fails or is cancelled ---
|
|
444
|
+
await app.updateTransactionStatus(paymentIntentId, 'failed');
|
|
445
|
+
|
|
446
|
+
// --- Querying balance and history ---
|
|
447
|
+
const balance = app.getBalance();
|
|
448
|
+
|
|
449
|
+
const { transactions, total } = await app.getTransactions(50, 0);
|
|
450
|
+
|
|
451
|
+
const tx = await app.getTransactionByPaymentId(paymentIntentId);
|
|
452
|
+
console.log(tx?.status); // 'pending' | 'succeeded' | 'failed' | 'cancelled'
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
To push real-time balance updates to a connected client (e.g. via SSE), subscribe to the balance emitter before crediting the user:
|
|
456
|
+
|
|
457
|
+
```typescript
|
|
458
|
+
const emitter = app.getBalanceMessageEmitter(userId);
|
|
459
|
+
emitter.on('update', (newBalance: number) => {
|
|
460
|
+
// Push newBalance to the client
|
|
461
|
+
});
|
|
462
|
+
```
|
|
463
|
+
|
|
355
464
|
## Data Storage
|
|
356
465
|
|
|
357
466
|
Briyah stores data in the following structure:
|
|
@@ -30,16 +30,14 @@ let StripeController = class StripeController {
|
|
|
30
30
|
const userId = req.user.userId;
|
|
31
31
|
const { amount } = body;
|
|
32
32
|
const appService = this.userServiceManager.getAppService(userId);
|
|
33
|
-
const
|
|
34
|
-
const result = await this.stripeService.createPaymentIntent(userId, amount, transactionService);
|
|
33
|
+
const result = await this.stripeService.createPaymentIntent(userId, amount, appService);
|
|
35
34
|
return result;
|
|
36
35
|
}
|
|
37
36
|
async createCheckoutSession(req, body) {
|
|
38
37
|
const userId = req.user.userId;
|
|
39
38
|
const { amount } = body;
|
|
40
39
|
const appService = this.userServiceManager.getAppService(userId);
|
|
41
|
-
const
|
|
42
|
-
const result = await this.stripeService.createCheckoutSession(userId, amount, transactionService);
|
|
40
|
+
const result = await this.stripeService.createCheckoutSession(userId, amount, appService);
|
|
43
41
|
return result;
|
|
44
42
|
}
|
|
45
43
|
async getStripeConfig() {
|
|
@@ -95,8 +93,7 @@ let StripeController = class StripeController {
|
|
|
95
93
|
const parsedLimit = limit ? parseInt(limit, 10) : 50;
|
|
96
94
|
const parsedOffset = offset ? parseInt(offset, 10) : 0;
|
|
97
95
|
const appService = this.userServiceManager.getAppService(userId);
|
|
98
|
-
const
|
|
99
|
-
const result = await transactionService.getTransactions(parsedLimit, parsedOffset);
|
|
96
|
+
const result = await appService.getTransactions(parsedLimit, parsedOffset);
|
|
100
97
|
return result;
|
|
101
98
|
}
|
|
102
99
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import Stripe from 'stripe';
|
|
2
|
-
import { TransactionService } from './transaction.service';
|
|
3
2
|
import { AppService } from '../app.service';
|
|
4
3
|
type StripeInstance = ReturnType<typeof Stripe>;
|
|
5
4
|
type StripeEvent = ReturnType<StripeInstance['webhooks']['constructEvent']>;
|
|
@@ -11,11 +10,11 @@ export declare class StripeService {
|
|
|
11
10
|
private publishableKey;
|
|
12
11
|
private webhookSecret;
|
|
13
12
|
constructor();
|
|
14
|
-
createPaymentIntent(userId: string, amount: number,
|
|
13
|
+
createPaymentIntent(userId: string, amount: number, appService: AppService): Promise<{
|
|
15
14
|
clientSecret: string;
|
|
16
15
|
publishableKey: string;
|
|
17
16
|
}>;
|
|
18
|
-
createCheckoutSession(userId: string, amount: number,
|
|
17
|
+
createCheckoutSession(userId: string, amount: number, appService: AppService): Promise<{
|
|
19
18
|
url: string;
|
|
20
19
|
}>;
|
|
21
20
|
getStripeConfig(): {
|
|
@@ -40,7 +40,7 @@ let StripeService = class StripeService {
|
|
|
40
40
|
this.minPaymentAmount = parseFloat(process.env.MIN_PAYMENT_AMOUNT || '5.00');
|
|
41
41
|
this.maxPaymentAmount = parseFloat(process.env.MAX_PAYMENT_AMOUNT || '500.00');
|
|
42
42
|
}
|
|
43
|
-
async createPaymentIntent(userId, amount,
|
|
43
|
+
async createPaymentIntent(userId, amount, appService) {
|
|
44
44
|
if (!amount || amount <= 0) {
|
|
45
45
|
throw new common_1.BadRequestException('Amount must be greater than 0');
|
|
46
46
|
}
|
|
@@ -62,7 +62,7 @@ let StripeService = class StripeService {
|
|
|
62
62
|
enabled: true,
|
|
63
63
|
},
|
|
64
64
|
});
|
|
65
|
-
await
|
|
65
|
+
await appService.recordTransaction(amount, paymentIntent.id, 'pending');
|
|
66
66
|
return {
|
|
67
67
|
clientSecret: paymentIntent.client_secret,
|
|
68
68
|
publishableKey: this.publishableKey,
|
|
@@ -73,7 +73,7 @@ let StripeService = class StripeService {
|
|
|
73
73
|
throw new common_1.InternalServerErrorException('Failed to create payment intent');
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
|
-
async createCheckoutSession(userId, amount,
|
|
76
|
+
async createCheckoutSession(userId, amount, appService) {
|
|
77
77
|
if (!amount || amount <= 0) {
|
|
78
78
|
throw new common_1.BadRequestException('Amount must be greater than 0');
|
|
79
79
|
}
|
|
@@ -113,7 +113,7 @@ let StripeService = class StripeService {
|
|
|
113
113
|
},
|
|
114
114
|
});
|
|
115
115
|
if (session.payment_intent) {
|
|
116
|
-
await
|
|
116
|
+
await appService.recordTransaction(amount, session.payment_intent, 'pending');
|
|
117
117
|
}
|
|
118
118
|
return {
|
|
119
119
|
url: session.url,
|
|
@@ -148,8 +148,7 @@ let StripeService = class StripeService {
|
|
|
148
148
|
}
|
|
149
149
|
const amount = paymentIntent.amount / 100;
|
|
150
150
|
logger_1.logger.log(`[Stripe Webhook] Amount: $${amount.toFixed(2)}`);
|
|
151
|
-
const
|
|
152
|
-
const existingTransaction = await transactionService.getTransactionByPaymentIntent(paymentIntent.id);
|
|
151
|
+
const existingTransaction = await appService.getTransactionByPaymentId(paymentIntent.id);
|
|
153
152
|
logger_1.logger.log(`[Stripe Webhook] Existing transaction:`, existingTransaction);
|
|
154
153
|
if (existingTransaction?.status === 'succeeded') {
|
|
155
154
|
logger_1.logger.log(`Transaction ${paymentIntent.id} already processed, skipping`);
|
|
@@ -162,7 +161,7 @@ let StripeService = class StripeService {
|
|
|
162
161
|
const balanceAfter = await appService.getBalance();
|
|
163
162
|
logger_1.logger.log(`[Stripe Webhook] Balance after: $${balanceAfter.toFixed(2)}`);
|
|
164
163
|
logger_1.logger.log(`[Stripe Webhook] Updating transaction status to 'succeeded'`);
|
|
165
|
-
await
|
|
164
|
+
await appService.updateTransactionStatus(paymentIntent.id, 'succeeded');
|
|
166
165
|
logger_1.logger.log(`[Stripe Webhook] Checking for paused stories to resume...`);
|
|
167
166
|
const resumedCount = await appService.resumePausedStories();
|
|
168
167
|
if (resumedCount > 0) {
|
|
@@ -182,8 +181,7 @@ let StripeService = class StripeService {
|
|
|
182
181
|
logger_1.logger.error('Payment Intent missing userId in metadata:', paymentIntent.id);
|
|
183
182
|
return;
|
|
184
183
|
}
|
|
185
|
-
|
|
186
|
-
await transactionService.updateTransactionStatus(paymentIntent.id, 'failed');
|
|
184
|
+
await appService.updateTransactionStatus(paymentIntent.id, 'failed');
|
|
187
185
|
logger_1.logger.log(`Payment failed for user ${userId}: ${paymentIntent.id}`);
|
|
188
186
|
}
|
|
189
187
|
catch (error) {
|
|
@@ -5,9 +5,9 @@ export declare class TransactionService {
|
|
|
5
5
|
private configService;
|
|
6
6
|
private transactionsDir;
|
|
7
7
|
constructor(userId: string, configService: ConfigurationService);
|
|
8
|
-
recordTransaction(amount: number,
|
|
9
|
-
updateTransactionStatus(
|
|
10
|
-
|
|
8
|
+
recordTransaction(amount: number, paymentId: string, status?: 'pending' | 'succeeded' | 'failed' | 'cancelled'): Promise<Transaction>;
|
|
9
|
+
updateTransactionStatus(paymentId: string, status: 'pending' | 'succeeded' | 'failed' | 'cancelled'): Promise<void>;
|
|
10
|
+
getTransactionByPaymentId(paymentId: string): Promise<Transaction | null>;
|
|
11
11
|
getTransactions(limit?: number, offset?: number): Promise<{
|
|
12
12
|
transactions: Transaction[];
|
|
13
13
|
total: number;
|
|
@@ -51,19 +51,19 @@ class TransactionService {
|
|
|
51
51
|
fs.mkdirSync(this.transactionsDir, { recursive: true });
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
-
async recordTransaction(amount,
|
|
54
|
+
async recordTransaction(amount, paymentId, status = 'pending') {
|
|
55
55
|
const timestamp = Date.now();
|
|
56
56
|
const transaction = {
|
|
57
57
|
id: (0, zod_1.uuidv4)().toString(),
|
|
58
58
|
userId: this.userId,
|
|
59
59
|
amount,
|
|
60
60
|
currency: 'usd',
|
|
61
|
-
|
|
61
|
+
paymentId,
|
|
62
62
|
status,
|
|
63
63
|
createdAt: timestamp,
|
|
64
64
|
updatedAt: timestamp,
|
|
65
65
|
};
|
|
66
|
-
const filename = `${timestamp}-${
|
|
66
|
+
const filename = `${timestamp}-${paymentId}.json`;
|
|
67
67
|
const filePath = path.join(this.transactionsDir, filename);
|
|
68
68
|
try {
|
|
69
69
|
fs.writeFileSync(filePath, JSON.stringify(transaction, null, 2), 'utf-8');
|
|
@@ -74,31 +74,31 @@ class TransactionService {
|
|
|
74
74
|
throw error;
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
|
-
async updateTransactionStatus(
|
|
77
|
+
async updateTransactionStatus(paymentId, status) {
|
|
78
78
|
try {
|
|
79
|
-
const transaction = await this.
|
|
79
|
+
const transaction = await this.getTransactionByPaymentId(paymentId);
|
|
80
80
|
if (!transaction) {
|
|
81
|
-
logger_1.logger.error(`Transaction not found for payment
|
|
81
|
+
logger_1.logger.error(`Transaction not found for payment ID ${paymentId}`);
|
|
82
82
|
return;
|
|
83
83
|
}
|
|
84
84
|
transaction.status = status;
|
|
85
85
|
transaction.updatedAt = Date.now();
|
|
86
86
|
const files = fs.readdirSync(this.transactionsDir);
|
|
87
|
-
const matchingFile = files.find((file) => file.includes(
|
|
87
|
+
const matchingFile = files.find((file) => file.includes(paymentId));
|
|
88
88
|
if (matchingFile) {
|
|
89
89
|
const filePath = path.join(this.transactionsDir, matchingFile);
|
|
90
90
|
fs.writeFileSync(filePath, JSON.stringify(transaction, null, 2), 'utf-8');
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
catch (error) {
|
|
94
|
-
logger_1.logger.error(`Error updating transaction status for ${
|
|
94
|
+
logger_1.logger.error(`Error updating transaction status for ${paymentId}:`, error);
|
|
95
95
|
throw error;
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
|
-
async
|
|
98
|
+
async getTransactionByPaymentId(paymentId) {
|
|
99
99
|
try {
|
|
100
100
|
const files = fs.readdirSync(this.transactionsDir);
|
|
101
|
-
const matchingFile = files.find((file) => file.includes(
|
|
101
|
+
const matchingFile = files.find((file) => file.includes(paymentId));
|
|
102
102
|
if (!matchingFile) {
|
|
103
103
|
return null;
|
|
104
104
|
}
|
|
@@ -107,7 +107,7 @@ class TransactionService {
|
|
|
107
107
|
return JSON.parse(content);
|
|
108
108
|
}
|
|
109
109
|
catch (error) {
|
|
110
|
-
logger_1.logger.error(`Error getting transaction for payment
|
|
110
|
+
logger_1.logger.error(`Error getting transaction for payment ID ${paymentId}:`, error);
|
|
111
111
|
return null;
|
|
112
112
|
}
|
|
113
113
|
}
|
|
@@ -1415,10 +1415,16 @@ let AppController = class AppController {
|
|
|
1415
1415
|
const updateHandler = (data) => {
|
|
1416
1416
|
subscriber.next({ data });
|
|
1417
1417
|
};
|
|
1418
|
-
emitter.on('
|
|
1418
|
+
emitter.on('story-state', updateHandler);
|
|
1419
|
+
emitter.on('suggest-introduce-character', updateHandler);
|
|
1420
|
+
emitter.on('suggest-progress-chapter', updateHandler);
|
|
1421
|
+
emitter.on('story-error', updateHandler);
|
|
1419
1422
|
return () => {
|
|
1420
1423
|
logger_1.logger.log(`[SSE] Cleanup for story ${storyId}`);
|
|
1421
|
-
emitter.off('
|
|
1424
|
+
emitter.off('story-state', updateHandler);
|
|
1425
|
+
emitter.off('suggest-introduce-character', updateHandler);
|
|
1426
|
+
emitter.off('suggest-progress-chapter', updateHandler);
|
|
1427
|
+
emitter.off('story-error', updateHandler);
|
|
1422
1428
|
};
|
|
1423
1429
|
});
|
|
1424
1430
|
}
|
|
@@ -21,7 +21,7 @@ import { TransactionService } from './app/transaction.service';
|
|
|
21
21
|
import { AgentFactory } from './ai/agent-factory';
|
|
22
22
|
import { RoomFactory } from './room/room-factory';
|
|
23
23
|
import { EventEmitter } from 'events';
|
|
24
|
-
import { AgentInfo, RoomInfo, RoomDetails, CreateRoomResponse, FileList, PromptFileContent, PromptFoldersResponse, PromptFilesResponse, PromptScope, ProcessTextResponse, PreparedPromptResponse, AttachDocumentResponse, AgentMessagesResponse, RoomMessagesResponse, StoryInfo, StoryState, Character } from '../../shared/types/app.types';
|
|
24
|
+
import { AgentInfo, RoomInfo, RoomDetails, CreateRoomResponse, FileList, PromptFileContent, PromptFoldersResponse, PromptFilesResponse, PromptScope, ProcessTextResponse, PreparedPromptResponse, AttachDocumentResponse, AgentMessagesResponse, RoomMessagesResponse, StoryInfo, StoryState, Character, Transaction, TransactionHistoryResponse } from '../../shared/types/app.types';
|
|
25
25
|
import { RoomMessage } from './room/message';
|
|
26
26
|
export declare class AppService {
|
|
27
27
|
private readonly aiFactoryService;
|
|
@@ -166,7 +166,10 @@ export declare class AppService {
|
|
|
166
166
|
savePlotPlan(storyId: string, content: string): Promise<void>;
|
|
167
167
|
getBalance(): number;
|
|
168
168
|
addBalance(amount: number): void;
|
|
169
|
-
|
|
169
|
+
recordTransaction(amount: number, paymentId: string, status?: 'pending' | 'succeeded' | 'failed' | 'cancelled'): Promise<Transaction>;
|
|
170
|
+
updateTransactionStatus(paymentId: string, status: 'pending' | 'succeeded' | 'failed' | 'cancelled'): Promise<void>;
|
|
171
|
+
getTransactionByPaymentId(paymentId: string): Promise<Transaction | null>;
|
|
172
|
+
getTransactions(limit?: number, offset?: number): Promise<TransactionHistoryResponse>;
|
|
170
173
|
listUserArtifacts(): ArtifactMetadata[];
|
|
171
174
|
getUserArtifact(artifactId: string): string | Buffer | null;
|
|
172
175
|
createUserArtifact(name: string, content: string): string;
|
|
@@ -1155,8 +1155,17 @@ class AppService {
|
|
|
1155
1155
|
addBalance(amount) {
|
|
1156
1156
|
return this.balanceService.addBalance(amount);
|
|
1157
1157
|
}
|
|
1158
|
-
|
|
1159
|
-
return this.transactionService;
|
|
1158
|
+
async recordTransaction(amount, paymentId, status = 'pending') {
|
|
1159
|
+
return this.transactionService.recordTransaction(amount, paymentId, status);
|
|
1160
|
+
}
|
|
1161
|
+
async updateTransactionStatus(paymentId, status) {
|
|
1162
|
+
return this.transactionService.updateTransactionStatus(paymentId, status);
|
|
1163
|
+
}
|
|
1164
|
+
async getTransactionByPaymentId(paymentId) {
|
|
1165
|
+
return this.transactionService.getTransactionByPaymentId(paymentId);
|
|
1166
|
+
}
|
|
1167
|
+
async getTransactions(limit = 50, offset = 0) {
|
|
1168
|
+
return this.transactionService.getTransactions(limit, offset);
|
|
1160
1169
|
}
|
|
1161
1170
|
listUserArtifacts() {
|
|
1162
1171
|
return this.artifactService.listArtifacts();
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export { Briyah } from './briyah';
|
|
2
2
|
export { BriyahConfigService, BriyahConfigOptions } from './briyah-config';
|
|
3
3
|
export type { AppService } from '../app.service';
|
|
4
|
-
export type { AgentInfo, CreateAgentResponse, RoomInfo, RoomDetails, CreateRoomResponse, StoryInfo, CreateStoryResponse, ProcessTextResponse, FileList, PromptFileContent, AttachDocumentResponse, AgentMessagesResponse, RoomMessagesResponse, StoryState, Message, MessageAction, ModelInfo, ArtifactMetadata, PreparedPromptResponse, PromptScope, PromptFolder, PromptFoldersResponse, PromptFile, PromptFilesResponse, StoryIdea, Character, ChapterInfo, } from '../../../shared/types/app.types';
|
|
4
|
+
export type { AgentInfo, CreateAgentResponse, RoomInfo, RoomDetails, CreateRoomResponse, StoryInfo, CreateStoryResponse, ProcessTextResponse, FileList, PromptFileContent, AttachDocumentResponse, AgentMessagesResponse, RoomMessagesResponse, StoryState, Message, MessageAction, ModelInfo, ArtifactMetadata, PreparedPromptResponse, PromptScope, PromptFolder, PromptFoldersResponse, PromptFile, PromptFilesResponse, StoryIdea, Transaction, TransactionHistoryResponse, StoryStateEvent, StoryIntroduceCharacterEvent, StoryProgressChapterEvent, StoryErrorEvent, Character, ChapterInfo, } from '../../../shared/types/app.types';
|
|
5
5
|
export type { LoggingOptions } from './briyah-config';
|
|
6
6
|
export { Agent } from '../ai/agent';
|
|
7
7
|
export { Room } from '../room/room';
|
|
8
|
+
export { RoomMessage } from '../room/message';
|
|
9
|
+
export type { Artifact } from '../room/artifact';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Room = exports.Agent = exports.BriyahConfigService = exports.Briyah = void 0;
|
|
3
|
+
exports.RoomMessage = exports.Room = exports.Agent = exports.BriyahConfigService = exports.Briyah = void 0;
|
|
4
4
|
var briyah_1 = require("./briyah");
|
|
5
5
|
Object.defineProperty(exports, "Briyah", { enumerable: true, get: function () { return briyah_1.Briyah; } });
|
|
6
6
|
var briyah_config_1 = require("./briyah-config");
|
|
@@ -9,3 +9,5 @@ var agent_1 = require("../ai/agent");
|
|
|
9
9
|
Object.defineProperty(exports, "Agent", { enumerable: true, get: function () { return agent_1.Agent; } });
|
|
10
10
|
var room_1 = require("../room/room");
|
|
11
11
|
Object.defineProperty(exports, "Room", { enumerable: true, get: function () { return room_1.Room; } });
|
|
12
|
+
var message_1 = require("../room/message");
|
|
13
|
+
Object.defineProperty(exports, "RoomMessage", { enumerable: true, get: function () { return message_1.RoomMessage; } });
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
-
import {
|
|
2
|
+
import { StoryState } from '../../../shared/types/app.types';
|
|
3
3
|
export declare class StoryMessageService {
|
|
4
4
|
private messageEmitters;
|
|
5
5
|
getOrCreateEmitter(storyId: string): EventEmitter;
|
|
6
6
|
getEmitter(storyId: string): EventEmitter | undefined;
|
|
7
|
-
|
|
7
|
+
emitStoryState(storyId: string, state: StoryState): void;
|
|
8
|
+
emitIntroduceCharacter(storyId: string, characterName?: string): void;
|
|
9
|
+
emitProgressChapter(storyId: string): void;
|
|
8
10
|
emitError(storyId: string, error: Error): void;
|
|
9
11
|
cleanup(storyId: string): void;
|
|
10
12
|
}
|
|
@@ -22,25 +22,44 @@ let StoryMessageService = class StoryMessageService {
|
|
|
22
22
|
getEmitter(storyId) {
|
|
23
23
|
return this.messageEmitters.get(storyId);
|
|
24
24
|
}
|
|
25
|
-
|
|
25
|
+
emitStoryState(storyId, state) {
|
|
26
26
|
const emitter = this.messageEmitters.get(storyId);
|
|
27
27
|
if (emitter) {
|
|
28
|
-
const
|
|
28
|
+
const payload = { type: 'story-state', state, timestamp: Date.now() };
|
|
29
|
+
emitter.emit('story-state', payload);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
emitIntroduceCharacter(storyId, characterName) {
|
|
33
|
+
const emitter = this.messageEmitters.get(storyId);
|
|
34
|
+
if (emitter) {
|
|
35
|
+
const payload = {
|
|
36
|
+
type: 'suggest-introduce-character',
|
|
37
|
+
characterName,
|
|
29
38
|
timestamp: Date.now(),
|
|
30
|
-
...update
|
|
31
39
|
};
|
|
32
|
-
emitter.emit('
|
|
40
|
+
emitter.emit('suggest-introduce-character', payload);
|
|
33
41
|
}
|
|
34
42
|
}
|
|
35
|
-
|
|
43
|
+
emitProgressChapter(storyId) {
|
|
36
44
|
const emitter = this.messageEmitters.get(storyId);
|
|
37
45
|
if (emitter) {
|
|
38
|
-
|
|
46
|
+
const payload = {
|
|
47
|
+
type: 'suggest-progress-chapter',
|
|
39
48
|
timestamp: Date.now(),
|
|
40
|
-
|
|
49
|
+
};
|
|
50
|
+
emitter.emit('suggest-progress-chapter', payload);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
emitError(storyId, error) {
|
|
54
|
+
const emitter = this.messageEmitters.get(storyId);
|
|
55
|
+
if (emitter) {
|
|
56
|
+
const payload = {
|
|
57
|
+
type: 'story-error',
|
|
41
58
|
errorType: error.name,
|
|
42
59
|
message: error.message,
|
|
43
|
-
|
|
60
|
+
timestamp: Date.now(),
|
|
61
|
+
};
|
|
62
|
+
emitter.emit('story-error', payload);
|
|
44
63
|
}
|
|
45
64
|
}
|
|
46
65
|
cleanup(storyId) {
|
|
@@ -138,10 +138,7 @@ let StoryService = class StoryService {
|
|
|
138
138
|
totalInputTokens: story.totalInputTokens || 0,
|
|
139
139
|
totalOutputTokens: story.totalOutputTokens || 0,
|
|
140
140
|
};
|
|
141
|
-
this.messageService.
|
|
142
|
-
type: 'state',
|
|
143
|
-
state: stateUpdate
|
|
144
|
-
});
|
|
141
|
+
this.messageService.emitStoryState(storyId, stateUpdate);
|
|
145
142
|
}
|
|
146
143
|
catch (error) {
|
|
147
144
|
logger_1.logger.error(`Error emitting story state update for ${storyId}:`, error);
|
|
@@ -1212,7 +1209,7 @@ let StoryService = class StoryService {
|
|
|
1212
1209
|
agent.disableBalanceCheck = true;
|
|
1213
1210
|
agent.save();
|
|
1214
1211
|
}
|
|
1215
|
-
this.progressService.emitProgress(storyId, 'profiles
|
|
1212
|
+
this.progressService.emitProgress(storyId, 'profiles', 'Updating plot plan and character profiles...');
|
|
1216
1213
|
const updatedPlotPlan = await this.updatePlotPlan(room, narrator);
|
|
1217
1214
|
await this.updateCharacterProfiles(room, characterAgents, updatedPlotPlan);
|
|
1218
1215
|
await this.updateStoryCost(storyId);
|
|
@@ -1627,13 +1624,7 @@ let StoryService = class StoryService {
|
|
|
1627
1624
|
story.declinedCharacters = [];
|
|
1628
1625
|
this.storyStore.updateStoryMetadata(storyId, story);
|
|
1629
1626
|
}
|
|
1630
|
-
this.messageService.
|
|
1631
|
-
type: 'suggestion',
|
|
1632
|
-
suggestion: {
|
|
1633
|
-
type: 'progress_chapter',
|
|
1634
|
-
timestamp: Date.now()
|
|
1635
|
-
}
|
|
1636
|
-
});
|
|
1627
|
+
this.messageService.emitProgressChapter(storyId);
|
|
1637
1628
|
return;
|
|
1638
1629
|
}
|
|
1639
1630
|
let agentCompactionThreshold = Number(process.env.AGENT_COMPACTION_THRESHOLD) || 150000;
|
|
@@ -1647,14 +1638,7 @@ let StoryService = class StoryService {
|
|
|
1647
1638
|
logger_1.logger.log(`Character ${newCharacterName} was declined, skipping prompt`);
|
|
1648
1639
|
return;
|
|
1649
1640
|
}
|
|
1650
|
-
this.messageService.
|
|
1651
|
-
type: 'suggestion',
|
|
1652
|
-
suggestion: {
|
|
1653
|
-
type: 'introduce_character',
|
|
1654
|
-
characterName: newCharacterName,
|
|
1655
|
-
timestamp: Date.now()
|
|
1656
|
-
}
|
|
1657
|
-
});
|
|
1641
|
+
this.messageService.emitIntroduceCharacter(storyId, newCharacterName);
|
|
1658
1642
|
}
|
|
1659
1643
|
return;
|
|
1660
1644
|
}
|
|
@@ -241,20 +241,25 @@ export interface StoryState {
|
|
|
241
241
|
totalInputTokens: number;
|
|
242
242
|
totalOutputTokens: number;
|
|
243
243
|
}
|
|
244
|
-
export interface
|
|
245
|
-
type: '
|
|
244
|
+
export interface StoryStateEvent {
|
|
245
|
+
type: 'story-state';
|
|
246
|
+
state: StoryState;
|
|
247
|
+
timestamp: number;
|
|
248
|
+
}
|
|
249
|
+
export interface StoryIntroduceCharacterEvent {
|
|
250
|
+
type: 'suggest-introduce-character';
|
|
246
251
|
characterName?: string;
|
|
247
252
|
timestamp: number;
|
|
248
253
|
}
|
|
249
|
-
export interface
|
|
250
|
-
type: '
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
error
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
254
|
+
export interface StoryProgressChapterEvent {
|
|
255
|
+
type: 'suggest-progress-chapter';
|
|
256
|
+
timestamp: number;
|
|
257
|
+
}
|
|
258
|
+
export interface StoryErrorEvent {
|
|
259
|
+
type: 'story-error';
|
|
260
|
+
message: string;
|
|
261
|
+
errorType?: string;
|
|
262
|
+
timestamp: number;
|
|
258
263
|
}
|
|
259
264
|
export interface ChaptersResponse {
|
|
260
265
|
chapters: ChapterInfo[];
|
|
@@ -284,7 +289,7 @@ export interface Transaction {
|
|
|
284
289
|
userId: string;
|
|
285
290
|
amount: number;
|
|
286
291
|
currency: string;
|
|
287
|
-
|
|
292
|
+
paymentId: string;
|
|
288
293
|
status: 'pending' | 'succeeded' | 'failed' | 'cancelled';
|
|
289
294
|
createdAt: number;
|
|
290
295
|
updatedAt: number;
|
package/docs/assets/hierarchy.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
window.hierarchyData = "
|
|
1
|
+
window.hierarchyData = "eJx1jc0KwjAQhN9lzqklLRbdd/DitfQQ2tUG0wSy8VTy7hL/KIKngZ1v51sRQ0gC6jvdDgqRL47HZIMX0IpOtyW8WRiEE4uYK0PhZv0Eavadwj06EKxPHC9mZKnf1G5Oi4PC6IwICEmmqrxVX7SUs3VTZA/qtdbHISuU3DjPISy/Xt0cPt7nOku9wf6KX4ec8wP/YVA+"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
window.navigationData = "
|
|
1
|
+
window.navigationData = "eJyNlk1P4zAQhv+Lz9WyVAJ2e2MLCCTQVpQb4mA508QisS17iqhW/PdVQpo6iT321e87j5PJfOT1H0P4RLZiT+AcL+FaoNSKLZjhWLEVA7Vv3NlI/FFhU7MFe5eqYKtfX4uBcV2CwlOsqLlz4M6643HU+dKP+2PlgVfzwO/zdORaq50st2A/pIAYZmSimM9aN3NIe5qK6tMUDu5FitEl6kHt9IkgFYLdcXFMY6uOEcuLyymiv8o9gzNaOYjjpk4SbcwsxT5vkEmIRbnjAsOIXswBPAHygiMnQUcTCUTkorrRYt+AQjplQSsF90vvr2m7xwXJAR+FXVfcINhoqXh6AmO5QLAxyLdKIixwhK6WyNQFfGls2zYZVN+Whm5R20MGdeSjsHeyhkfpwiV9FCnAoy5Lqcj6GFso2GwGeZTgCJqE6wLqaF0NKoXYWDDcQrGxujF0VYStNFwLcO4FPlPkmS+BbQy2HytG6+U8yForHK3CIKt35SHpYR7wZWB1XUR63zfkgrKecOyk0G1X3wByWYdbwtNTmGg9H8UUIGuhhowUuBswt9Zqe/sRK5aJJ4l7KCC8EQc1jYgla1AzEGh1sRcwrJDEG0YCkhdtrC4tONfvu8QtIXfyii1yDH/vk5wHSTzdyUPhXixXjk9+0j2Up2di7qVLbsS4PT0ctkIbj4oHM0yDTpoQfv6+Or9Yfr39ByjAXqw="
|