briyah 1.1.3 → 1.1.5
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 +14 -1
- package/data/common/config/image_models.json +6 -0
- package/data/common/config/markup +1 -1
- package/data/common/config/story_models.json +7 -0
- package/dist-sdk/server/src/ai/LLM/anthropic.service.js +6 -3
- package/dist-sdk/server/src/ai/LLM/base-ai.service.js +2 -1
- package/dist-sdk/server/src/app.controller.d.ts +11 -2
- package/dist-sdk/server/src/app.controller.js +167 -3
- package/dist-sdk/server/src/app.service.d.ts +1 -0
- package/dist-sdk/server/src/app.service.js +23 -11
- package/dist-sdk/server/src/auth/users.service.js +2 -2
- package/dist-sdk/server/src/common/errors.d.ts +3 -0
- package/dist-sdk/server/src/common/errors.js +11 -1
- package/dist-sdk/server/src/config/configuration.service.d.ts +2 -0
- package/dist-sdk/server/src/config/configuration.service.js +8 -0
- package/dist-sdk/server/src/library/library.service.d.ts +14 -0
- package/dist-sdk/server/src/library/library.service.js +165 -0
- package/dist-sdk/server/src/room/room.d.ts +4 -2
- package/dist-sdk/server/src/room/room.js +40 -19
- package/dist-sdk/server/src/shared/shared.module.js +3 -0
- package/dist-sdk/server/src/story/story.service.js +2 -2
- package/dist-sdk/shared/types/app.types.d.ts +22 -0
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/Agent.html +14 -14
- package/docs/classes/Briyah.html +12 -12
- package/docs/classes/BriyahConfigService.html +5 -5
- package/docs/classes/Room.html +31 -24
- package/docs/classes/RoomMessage.html +10 -10
- package/docs/enums/MessageAction.html +3 -3
- package/docs/hierarchy.html +1 -1
- package/docs/index.html +15 -3
- package/docs/interfaces/AgentInfo.html +2 -2
- package/docs/interfaces/AgentMessagesResponse.html +2 -2
- package/docs/interfaces/AppService.html +110 -107
- package/docs/interfaces/Artifact.html +3 -3
- 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 +3 -3
- package/docs/interfaces/StoryIdea.html +2 -2
- package/docs/interfaces/StoryInfo.html +3 -3
- package/docs/interfaces/StoryIntroduceCharacterEvent.html +3 -3
- package/docs/interfaces/StoryProgressChapterEvent.html +3 -3
- package/docs/interfaces/StoryState.html +5 -5
- package/docs/interfaces/StoryStateEvent.html +3 -3
- package/docs/interfaces/Transaction.html +2 -2
- package/docs/interfaces/TransactionHistoryResponse.html +2 -2
- package/docs/modules.html +1 -1
- package/docs/types/PromptScope.html +1 -1
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
# Briyah SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Briyah is an SDK for AI agents, multi-agent rooms, and interactive stories. It wraps the Briyah runtime as a single class with per-user data isolation and balance tracking, and supports Anthropic, OpenAI, Google, Grok, DeepSeek, Together, and Fal as LLM providers.
|
|
4
|
+
|
|
5
|
+
What's in the package:
|
|
6
|
+
|
|
7
|
+
- **Agents.** AI agents with a system prompt, persistent conversation history, attached documents, and per-call cost and token tracking. Histories can be summarized/compacted or cleared.
|
|
8
|
+
- **Rooms.** Multi-agent conversations with a shared goal. Agents exchange messages at different visibility levels (speak, whisper, think, shout), draft and approve shared artifacts, and a moderator can route turns.
|
|
9
|
+
- **Stories.** Text-based interactive fiction with a narrator, AI-played characters, and a human player. Stories progress through chapters and can introduce new characters mid-game. Story events (state updates, character suggestions, chapter transitions, errors) are delivered through an emitter the host app subscribes to.
|
|
10
|
+
- **Text processing.** One-shot `processText` for non-conversational use, with cost and token counts on the result.
|
|
11
|
+
- **File attachments.** Attach documents to agents as context. Supported file types vary by LLM provider.
|
|
12
|
+
- **Per-user data.** Agents, rooms, stories, attached files, balances, and transactions are scoped to a userId the host controls. Per-user directories keep state isolated.
|
|
13
|
+
- **Balances and transactions.** Track per-user balances against usage cost. Record pending, succeeded, failed, or cancelled transactions when integrating with a payment provider, credit balances on webhook confirmation, and resume stories that paused on insufficient funds. Briyah does not process payments itself.
|
|
14
|
+
- **Real-time event emitters.** Story-state and balance updates can be forwarded to SSE or websockets.
|
|
15
|
+
|
|
16
|
+
State is persisted as JSON files under a configurable data path; no external database is required.
|
|
4
17
|
|
|
5
18
|
## Installation
|
|
6
19
|
|
|
@@ -11,5 +11,11 @@
|
|
|
11
11
|
"description": "Mediocre quality; some character consistency",
|
|
12
12
|
"service": "OpenAI",
|
|
13
13
|
"model": "gpt-image-1-mini"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"name": "No images",
|
|
17
|
+
"description": "Disable image generation (no real API calls)",
|
|
18
|
+
"service": "",
|
|
19
|
+
"model": ""
|
|
14
20
|
}
|
|
15
21
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
11.330019880000021
|
|
@@ -155,11 +155,14 @@ let AnthropicAiService = class AnthropicAiService extends base_ai_service_1.Base
|
|
|
155
155
|
const systemBlocks = [];
|
|
156
156
|
if (instructionText)
|
|
157
157
|
systemBlocks.push({ type: 'text', text: instructionText });
|
|
158
|
-
|
|
158
|
+
const identityBlock = {
|
|
159
159
|
type: 'text',
|
|
160
160
|
text: `Your agent identity is ${agent.agentName}: ${agent.description}`,
|
|
161
|
-
|
|
162
|
-
|
|
161
|
+
};
|
|
162
|
+
if (cacheConfig) {
|
|
163
|
+
identityBlock.cache_control = cacheConfig;
|
|
164
|
+
}
|
|
165
|
+
systemBlocks.push(identityBlock);
|
|
163
166
|
const messageHistory = agent.history.map((msg) => ({
|
|
164
167
|
role: msg.role,
|
|
165
168
|
content: [{ type: 'text', text: msg.content }],
|
|
@@ -151,7 +151,8 @@ let BaseAiService = class BaseAiService {
|
|
|
151
151
|
if (!agentName) {
|
|
152
152
|
throw new Error('Agent name is required');
|
|
153
153
|
}
|
|
154
|
-
if (
|
|
154
|
+
if (this.getServiceName() !== 'Mock' &&
|
|
155
|
+
!(0, model_prices_1.isKnownModel)(modelName, this.getModelPricePrefix())) {
|
|
155
156
|
throw new Error(`Model '${modelName}' is not listed in model_prices.json for ${this.getServiceName()}. ` +
|
|
156
157
|
`Add a pricing entry before using this model.`);
|
|
157
158
|
}
|
|
@@ -4,13 +4,15 @@ import { Observable } from 'rxjs';
|
|
|
4
4
|
import { UserServiceManager } from './app/user-service-manager';
|
|
5
5
|
import { PublishedAgentsService } from './ai/published-agents.service';
|
|
6
6
|
import { PublishedRoomsService } from './room/published-rooms.service';
|
|
7
|
-
import {
|
|
7
|
+
import { LibraryService } from './library/library.service';
|
|
8
|
+
import { AgentInfo, CreateAgentResponse, UpdateAgentRequest, RoomInfo, RoomDetails, CreateRoomResponse, AgentMessagesResponse, RoomMessagesResponse, FileList, PromptFileContent, PromptFoldersResponse, PromptFilesResponse, PromptScope, CreatePromptFolderRequest, CreatePromptFileRequest, UpdatePromptFileRequest, ProcessTextResponse, PreparedPromptResponse, AttachDocumentResponse, StoryInfo, StoryState, Character, ModelInfo, StoryModelDefaults, ChapterInfo, StoryIdea, LibraryPromptsResponse, LibraryFilesResponse, LibraryFileContent, LibraryDefaultUrlResponse, CopyFromLibraryRequest } from '../../shared/types/app.types';
|
|
8
9
|
import { RoomMessage } from './room/message';
|
|
9
10
|
export declare class AppController {
|
|
10
11
|
private readonly userServiceManager;
|
|
11
12
|
private readonly publishedAgentsService;
|
|
12
13
|
private readonly publishedRoomsService;
|
|
13
|
-
|
|
14
|
+
private readonly libraryService;
|
|
15
|
+
constructor(userServiceManager: UserServiceManager, publishedAgentsService: PublishedAgentsService, publishedRoomsService: PublishedRoomsService, libraryService: LibraryService);
|
|
14
16
|
private getAppService;
|
|
15
17
|
listServices(req: ExpressRequest): string[];
|
|
16
18
|
listModels(req: ExpressRequest, aiServiceName: string): Promise<ModelInfo[]>;
|
|
@@ -44,6 +46,13 @@ export declare class AppController {
|
|
|
44
46
|
createPromptFile(req: ExpressRequest, folderName: string, body: CreatePromptFileRequest): Promise<void>;
|
|
45
47
|
updatePromptFile(req: ExpressRequest, folderName: string, fileName: string, body: UpdatePromptFileRequest): Promise<void>;
|
|
46
48
|
deletePromptFile(req: ExpressRequest, folderName: string, fileName: string): Promise<void>;
|
|
49
|
+
listLibraryPrompts(): LibraryPromptsResponse;
|
|
50
|
+
listLibraryFiles(folder: string): LibraryFilesResponse;
|
|
51
|
+
getLibraryFile(folder: string, file: string): LibraryFileContent;
|
|
52
|
+
getLibraryDefaultUrl(): LibraryDefaultUrlResponse;
|
|
53
|
+
proxyListRemote(url: string): Promise<LibraryPromptsResponse>;
|
|
54
|
+
proxyPreviewRemote(url: string, folder: string): Promise<LibraryFileContent>;
|
|
55
|
+
copyPromptFromLibrary(req: ExpressRequest, body: CopyFromLibraryRequest): Promise<void>;
|
|
47
56
|
listPromptFolders(req: ExpressRequest): string[];
|
|
48
57
|
listPrompts(req: ExpressRequest, agentId: string): string[];
|
|
49
58
|
runPreparedPrompt(req: ExpressRequest, agentId: string, promptName: string, body: {
|
|
@@ -50,11 +50,13 @@ const common_1 = require("@nestjs/common");
|
|
|
50
50
|
const platform_express_1 = require("@nestjs/platform-express");
|
|
51
51
|
const rxjs_1 = require("rxjs");
|
|
52
52
|
const jwt_auth_guard_1 = require("./auth/jwt-auth.guard");
|
|
53
|
+
const public_decorator_1 = require("./auth/public.decorator");
|
|
53
54
|
const agent_access_decorator_1 = require("./auth/agent-access.decorator");
|
|
54
55
|
const room_access_decorator_1 = require("./auth/room-access.decorator");
|
|
55
56
|
const user_service_manager_1 = require("./app/user-service-manager");
|
|
56
57
|
const published_agents_service_1 = require("./ai/published-agents.service");
|
|
57
58
|
const published_rooms_service_1 = require("./room/published-rooms.service");
|
|
59
|
+
const library_service_1 = require("./library/library.service");
|
|
58
60
|
const errors_1 = require("./common/errors");
|
|
59
61
|
const path = __importStar(require("path"));
|
|
60
62
|
const logger_1 = require("./common/logger");
|
|
@@ -62,10 +64,12 @@ let AppController = class AppController {
|
|
|
62
64
|
userServiceManager;
|
|
63
65
|
publishedAgentsService;
|
|
64
66
|
publishedRoomsService;
|
|
65
|
-
|
|
67
|
+
libraryService;
|
|
68
|
+
constructor(userServiceManager, publishedAgentsService, publishedRoomsService, libraryService) {
|
|
66
69
|
this.userServiceManager = userServiceManager;
|
|
67
70
|
this.publishedAgentsService = publishedAgentsService;
|
|
68
71
|
this.publishedRoomsService = publishedRoomsService;
|
|
72
|
+
this.libraryService = libraryService;
|
|
69
73
|
}
|
|
70
74
|
getAppService(req, agentId, roomId) {
|
|
71
75
|
let userId;
|
|
@@ -345,6 +349,105 @@ let AppController = class AppController {
|
|
|
345
349
|
throw new common_1.HttpException('Failed to delete prompt file', common_1.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
346
350
|
}
|
|
347
351
|
}
|
|
352
|
+
listLibraryPrompts() {
|
|
353
|
+
return { prompts: this.libraryService.listLocalPrompts() };
|
|
354
|
+
}
|
|
355
|
+
listLibraryFiles(folder) {
|
|
356
|
+
try {
|
|
357
|
+
return { files: this.libraryService.listLocalFiles(folder) };
|
|
358
|
+
}
|
|
359
|
+
catch (error) {
|
|
360
|
+
if (error instanceof errors_1.ValidationError) {
|
|
361
|
+
throw new common_1.BadRequestException(error.message);
|
|
362
|
+
}
|
|
363
|
+
if (error instanceof errors_1.NotFoundError) {
|
|
364
|
+
throw new common_1.NotFoundException(error.message);
|
|
365
|
+
}
|
|
366
|
+
throw error;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
getLibraryFile(folder, file) {
|
|
370
|
+
try {
|
|
371
|
+
return { content: this.libraryService.getLocalFileContent(folder, file) };
|
|
372
|
+
}
|
|
373
|
+
catch (error) {
|
|
374
|
+
if (error instanceof errors_1.ValidationError) {
|
|
375
|
+
throw new common_1.BadRequestException(error.message);
|
|
376
|
+
}
|
|
377
|
+
if (error instanceof errors_1.NotFoundError) {
|
|
378
|
+
throw new common_1.NotFoundException(error.message);
|
|
379
|
+
}
|
|
380
|
+
throw error;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
getLibraryDefaultUrl() {
|
|
384
|
+
return { url: process.env.WEB_URL ?? '' };
|
|
385
|
+
}
|
|
386
|
+
async proxyListRemote(url) {
|
|
387
|
+
if (!url)
|
|
388
|
+
throw new common_1.BadRequestException('url query param is required');
|
|
389
|
+
try {
|
|
390
|
+
return { prompts: await this.libraryService.listRemotePrompts(url) };
|
|
391
|
+
}
|
|
392
|
+
catch (error) {
|
|
393
|
+
if (error instanceof errors_1.ValidationError) {
|
|
394
|
+
throw new common_1.BadRequestException(error.message);
|
|
395
|
+
}
|
|
396
|
+
if (error instanceof errors_1.NotFoundError) {
|
|
397
|
+
throw new common_1.NotFoundException(error.message);
|
|
398
|
+
}
|
|
399
|
+
if (error instanceof errors_1.RemoteFetchError) {
|
|
400
|
+
throw new common_1.HttpException(error.message, common_1.HttpStatus.BAD_GATEWAY);
|
|
401
|
+
}
|
|
402
|
+
throw error;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
async proxyPreviewRemote(url, folder) {
|
|
406
|
+
if (!url)
|
|
407
|
+
throw new common_1.BadRequestException('url query param is required');
|
|
408
|
+
try {
|
|
409
|
+
return {
|
|
410
|
+
content: await this.libraryService.getRemoteFileContent(url, folder, 'system_instruction.prompt'),
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
catch (error) {
|
|
414
|
+
if (error instanceof errors_1.ValidationError) {
|
|
415
|
+
throw new common_1.BadRequestException(error.message);
|
|
416
|
+
}
|
|
417
|
+
if (error instanceof errors_1.NotFoundError) {
|
|
418
|
+
throw new common_1.NotFoundException(error.message);
|
|
419
|
+
}
|
|
420
|
+
if (error instanceof errors_1.RemoteFetchError) {
|
|
421
|
+
throw new common_1.HttpException(error.message, common_1.HttpStatus.BAD_GATEWAY);
|
|
422
|
+
}
|
|
423
|
+
throw error;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
async copyPromptFromLibrary(req, body) {
|
|
427
|
+
if (!body?.url || !body?.folder) {
|
|
428
|
+
throw new common_1.BadRequestException('url and folder are required');
|
|
429
|
+
}
|
|
430
|
+
const appService = this.getAppService(req);
|
|
431
|
+
try {
|
|
432
|
+
await this.libraryService.copyFromRemote(body.url, body.folder, appService.getUserPromptsDir());
|
|
433
|
+
}
|
|
434
|
+
catch (error) {
|
|
435
|
+
logger_1.logger.error(`[${req.user?.sub}] Error copying library prompt ${body.folder} from ${body.url}:`, error);
|
|
436
|
+
if (error instanceof errors_1.ValidationError) {
|
|
437
|
+
throw new common_1.BadRequestException(error.message);
|
|
438
|
+
}
|
|
439
|
+
if (error instanceof errors_1.NotFoundError) {
|
|
440
|
+
throw new common_1.NotFoundException(error.message);
|
|
441
|
+
}
|
|
442
|
+
if (error instanceof errors_1.RemoteFetchError) {
|
|
443
|
+
throw new common_1.HttpException(error.message, common_1.HttpStatus.BAD_GATEWAY);
|
|
444
|
+
}
|
|
445
|
+
if (error instanceof errors_1.OperationFailedError) {
|
|
446
|
+
throw new common_1.HttpException(error.message, common_1.HttpStatus.CONFLICT);
|
|
447
|
+
}
|
|
448
|
+
throw error;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
348
451
|
listPromptFolders(req) {
|
|
349
452
|
try {
|
|
350
453
|
const appService = this.getAppService(req);
|
|
@@ -556,6 +659,9 @@ let AppController = class AppController {
|
|
|
556
659
|
if (!body.publishedAgentName) {
|
|
557
660
|
throw new common_1.BadRequestException('publishedAgentName field is required');
|
|
558
661
|
}
|
|
662
|
+
if (body.publishedAgentName.length > 200) {
|
|
663
|
+
throw new common_1.BadRequestException('publishedAgentName too long (max 200 characters)');
|
|
664
|
+
}
|
|
559
665
|
try {
|
|
560
666
|
const appService = this.getAppService(req);
|
|
561
667
|
const result = await appService.publishAgentInstance(agentId, body.publishedAgentName);
|
|
@@ -875,6 +981,9 @@ let AppController = class AppController {
|
|
|
875
981
|
}
|
|
876
982
|
}
|
|
877
983
|
async publishRoom(req, templateId, body) {
|
|
984
|
+
if (body.publishedName && body.publishedName.length > 200) {
|
|
985
|
+
throw new common_1.BadRequestException('publishedName too long (max 200 characters)');
|
|
986
|
+
}
|
|
878
987
|
try {
|
|
879
988
|
const appService = this.getAppService(req);
|
|
880
989
|
const userId = req.user.sub;
|
|
@@ -1493,7 +1602,7 @@ let AppController = class AppController {
|
|
|
1493
1602
|
if (!roomDetails) {
|
|
1494
1603
|
throw new common_1.NotFoundException(`Room ${roomId} not found`);
|
|
1495
1604
|
}
|
|
1496
|
-
appService.ensureRoomStateCallback(roomId);
|
|
1605
|
+
await appService.ensureRoomStateCallback(roomId);
|
|
1497
1606
|
const emitter = appService.getRoomMessageEmitter(roomId);
|
|
1498
1607
|
return new rxjs_1.Observable((subscriber) => {
|
|
1499
1608
|
const updateHandler = (data) => {
|
|
@@ -1834,6 +1943,60 @@ __decorate([
|
|
|
1834
1943
|
__metadata("design:paramtypes", [Object, String, String]),
|
|
1835
1944
|
__metadata("design:returntype", Promise)
|
|
1836
1945
|
], AppController.prototype, "deletePromptFile", null);
|
|
1946
|
+
__decorate([
|
|
1947
|
+
(0, common_1.Get)('library/prompts'),
|
|
1948
|
+
(0, public_decorator_1.Public)(),
|
|
1949
|
+
__metadata("design:type", Function),
|
|
1950
|
+
__metadata("design:paramtypes", []),
|
|
1951
|
+
__metadata("design:returntype", Object)
|
|
1952
|
+
], AppController.prototype, "listLibraryPrompts", null);
|
|
1953
|
+
__decorate([
|
|
1954
|
+
(0, common_1.Get)('library/prompts/:folder/files'),
|
|
1955
|
+
(0, public_decorator_1.Public)(),
|
|
1956
|
+
__param(0, (0, common_1.Param)('folder')),
|
|
1957
|
+
__metadata("design:type", Function),
|
|
1958
|
+
__metadata("design:paramtypes", [String]),
|
|
1959
|
+
__metadata("design:returntype", Object)
|
|
1960
|
+
], AppController.prototype, "listLibraryFiles", null);
|
|
1961
|
+
__decorate([
|
|
1962
|
+
(0, common_1.Get)('library/prompts/:folder/files/:file'),
|
|
1963
|
+
(0, public_decorator_1.Public)(),
|
|
1964
|
+
__param(0, (0, common_1.Param)('folder')),
|
|
1965
|
+
__param(1, (0, common_1.Param)('file')),
|
|
1966
|
+
__metadata("design:type", Function),
|
|
1967
|
+
__metadata("design:paramtypes", [String, String]),
|
|
1968
|
+
__metadata("design:returntype", Object)
|
|
1969
|
+
], AppController.prototype, "getLibraryFile", null);
|
|
1970
|
+
__decorate([
|
|
1971
|
+
(0, common_1.Get)('library/default-url'),
|
|
1972
|
+
__metadata("design:type", Function),
|
|
1973
|
+
__metadata("design:paramtypes", []),
|
|
1974
|
+
__metadata("design:returntype", Object)
|
|
1975
|
+
], AppController.prototype, "getLibraryDefaultUrl", null);
|
|
1976
|
+
__decorate([
|
|
1977
|
+
(0, common_1.Get)('library/proxy/prompts'),
|
|
1978
|
+
__param(0, (0, common_1.Query)('url')),
|
|
1979
|
+
__metadata("design:type", Function),
|
|
1980
|
+
__metadata("design:paramtypes", [String]),
|
|
1981
|
+
__metadata("design:returntype", Promise)
|
|
1982
|
+
], AppController.prototype, "proxyListRemote", null);
|
|
1983
|
+
__decorate([
|
|
1984
|
+
(0, common_1.Get)('library/proxy/prompts/:folder/preview'),
|
|
1985
|
+
__param(0, (0, common_1.Query)('url')),
|
|
1986
|
+
__param(1, (0, common_1.Param)('folder')),
|
|
1987
|
+
__metadata("design:type", Function),
|
|
1988
|
+
__metadata("design:paramtypes", [String, String]),
|
|
1989
|
+
__metadata("design:returntype", Promise)
|
|
1990
|
+
], AppController.prototype, "proxyPreviewRemote", null);
|
|
1991
|
+
__decorate([
|
|
1992
|
+
(0, common_1.Post)('prompts/from-library'),
|
|
1993
|
+
(0, common_1.HttpCode)(common_1.HttpStatus.CREATED),
|
|
1994
|
+
__param(0, (0, common_1.Request)()),
|
|
1995
|
+
__param(1, (0, common_1.Body)()),
|
|
1996
|
+
__metadata("design:type", Function),
|
|
1997
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
1998
|
+
__metadata("design:returntype", Promise)
|
|
1999
|
+
], AppController.prototype, "copyPromptFromLibrary", null);
|
|
1837
2000
|
__decorate([
|
|
1838
2001
|
(0, common_1.Get)('list-prompt-folders'),
|
|
1839
2002
|
__param(0, (0, common_1.Request)()),
|
|
@@ -2578,5 +2741,6 @@ exports.AppController = AppController = __decorate([
|
|
|
2578
2741
|
(0, common_1.UseGuards)(jwt_auth_guard_1.JwtAuthGuard),
|
|
2579
2742
|
__metadata("design:paramtypes", [user_service_manager_1.UserServiceManager,
|
|
2580
2743
|
published_agents_service_1.PublishedAgentsService,
|
|
2581
|
-
published_rooms_service_1.PublishedRoomsService
|
|
2744
|
+
published_rooms_service_1.PublishedRoomsService,
|
|
2745
|
+
library_service_1.LibraryService])
|
|
2582
2746
|
], AppController);
|
|
@@ -95,6 +95,7 @@ export declare class AppService {
|
|
|
95
95
|
artifacts: any[];
|
|
96
96
|
}>;
|
|
97
97
|
publishArtifact(roomId: string, name: string, creator: string, body: string, viewers?: string[]): Promise<void>;
|
|
98
|
+
getUserPromptsDir(): string;
|
|
98
99
|
createPromptFolder(folderName: string): void;
|
|
99
100
|
deletePromptFolder(folderName: string): void;
|
|
100
101
|
updateAgent(agentId: string, updates: {
|
|
@@ -271,9 +271,7 @@ class AppService {
|
|
|
271
271
|
if (!agent) {
|
|
272
272
|
throw new errors_1.NotFoundError(`Agent with ID ${agentId} not found`);
|
|
273
273
|
}
|
|
274
|
-
const
|
|
275
|
-
let service = this.getAiServiceFromServiceName(serviceName);
|
|
276
|
-
const result = await service.preparedPrompt(agent, promptName, variables || {}, true);
|
|
274
|
+
const result = await agent.preparedPrompt(promptName, variables || {}, true);
|
|
277
275
|
return { result };
|
|
278
276
|
}
|
|
279
277
|
async listAgents() {
|
|
@@ -780,6 +778,9 @@ class AppService {
|
|
|
780
778
|
throw new errors_1.OperationFailedError('Artifact name is required');
|
|
781
779
|
room.publishArtifact(name, creator, body, viewers);
|
|
782
780
|
}
|
|
781
|
+
getUserPromptsDir() {
|
|
782
|
+
return this.configService.getUserPromptsDir();
|
|
783
|
+
}
|
|
783
784
|
createPromptFolder(folderName) {
|
|
784
785
|
const targetDir = path.join(this.configService.getUserPromptsDir(), folderName);
|
|
785
786
|
if (fs.existsSync(targetDir)) {
|
|
@@ -1033,7 +1034,7 @@ class AppService {
|
|
|
1033
1034
|
logger_1.logger.warn('Cannot set up SSE callback for room without ID');
|
|
1034
1035
|
return;
|
|
1035
1036
|
}
|
|
1036
|
-
room.setOnStateChange(() => {
|
|
1037
|
+
room.setOnStateChange('app-service', () => {
|
|
1037
1038
|
const messages = room.getLatestRoomMessages(0, false);
|
|
1038
1039
|
const latestMessage = messages.length > 0 ? messages[messages.length - 1] : undefined;
|
|
1039
1040
|
const totalCost = room
|
|
@@ -1222,18 +1223,29 @@ class AppService {
|
|
|
1222
1223
|
async convertLargePdfInBackground(artifactId, name, pdfDoc) {
|
|
1223
1224
|
const pageCount = pdfDoc.getPageCount();
|
|
1224
1225
|
logger_1.logger.log(`Converting large PDF with ${pageCount} pages concurrently for artifact ${artifactId}`);
|
|
1226
|
+
const perPageTimeoutMs = Number(process.env.PDF_CONVERT_PAGE_TIMEOUT_MS) || 2 * 60 * 1000;
|
|
1225
1227
|
try {
|
|
1226
1228
|
const conversionPromises = Array.from({ length: pageCount }, (_, pageIndex) => {
|
|
1227
1229
|
const pageNum = pageIndex + 1;
|
|
1228
1230
|
logger_1.logger.log(`Starting conversion for page ${pageNum}/${pageCount} for artifact ${artifactId}`);
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1231
|
+
let timeoutHandle;
|
|
1232
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
1233
|
+
timeoutHandle = setTimeout(() => {
|
|
1234
|
+
reject(new Error(`Timed out after ${perPageTimeoutMs}ms waiting for page ${pageNum}`));
|
|
1235
|
+
}, perPageTimeoutMs);
|
|
1236
|
+
});
|
|
1237
|
+
return Promise.race([this.convertSinglePagePDF(pdfDoc, pageIndex), timeoutPromise])
|
|
1238
|
+
.then((pageResponse) => {
|
|
1239
|
+
clearTimeout(timeoutHandle);
|
|
1240
|
+
return {
|
|
1241
|
+
pageNum,
|
|
1242
|
+
success: true,
|
|
1243
|
+
cost: pageResponse.cost,
|
|
1244
|
+
content: `**[Page ${pageNum}]** \n${pageResponse.markdownContent} \n`,
|
|
1245
|
+
};
|
|
1246
|
+
})
|
|
1236
1247
|
.catch((pageError) => {
|
|
1248
|
+
clearTimeout(timeoutHandle);
|
|
1237
1249
|
logger_1.logger.error(`Error converting page ${pageNum}:`, pageError);
|
|
1238
1250
|
return {
|
|
1239
1251
|
pageNum,
|
|
@@ -46,7 +46,7 @@ exports.UsersService = void 0;
|
|
|
46
46
|
const common_1 = require("@nestjs/common");
|
|
47
47
|
const fs = __importStar(require("fs"));
|
|
48
48
|
const path = __importStar(require("path"));
|
|
49
|
-
const
|
|
49
|
+
const crypto_1 = require("crypto");
|
|
50
50
|
const logger_1 = require("../common/logger");
|
|
51
51
|
let UsersService = class UsersService {
|
|
52
52
|
usersFilePath;
|
|
@@ -80,7 +80,7 @@ let UsersService = class UsersService {
|
|
|
80
80
|
fs.writeFileSync(this.usersFilePath, JSON.stringify(users, null, 2), 'utf-8');
|
|
81
81
|
}
|
|
82
82
|
generateUserId() {
|
|
83
|
-
return (0,
|
|
83
|
+
return (0, crypto_1.randomUUID)();
|
|
84
84
|
}
|
|
85
85
|
createUser(phoneNumber) {
|
|
86
86
|
const users = this.loadUsers();
|
|
@@ -7,6 +7,9 @@ export declare class ValidationError extends Error {
|
|
|
7
7
|
export declare class OperationFailedError extends Error {
|
|
8
8
|
constructor(message: string);
|
|
9
9
|
}
|
|
10
|
+
export declare class RemoteFetchError extends Error {
|
|
11
|
+
constructor(message: string);
|
|
12
|
+
}
|
|
10
13
|
export declare class InsufficientBalanceError extends Error {
|
|
11
14
|
constructor(message: string);
|
|
12
15
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.InsufficientBalanceError = exports.OperationFailedError = exports.ValidationError = exports.NotFoundError = void 0;
|
|
3
|
+
exports.InsufficientBalanceError = exports.RemoteFetchError = exports.OperationFailedError = exports.ValidationError = exports.NotFoundError = void 0;
|
|
4
4
|
class NotFoundError extends Error {
|
|
5
5
|
constructor(message) {
|
|
6
6
|
super(message);
|
|
@@ -31,6 +31,16 @@ class OperationFailedError extends Error {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
exports.OperationFailedError = OperationFailedError;
|
|
34
|
+
class RemoteFetchError extends Error {
|
|
35
|
+
constructor(message) {
|
|
36
|
+
super(message);
|
|
37
|
+
this.name = 'RemoteFetchError';
|
|
38
|
+
if (Error.captureStackTrace) {
|
|
39
|
+
Error.captureStackTrace(this, RemoteFetchError);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.RemoteFetchError = RemoteFetchError;
|
|
34
44
|
class InsufficientBalanceError extends Error {
|
|
35
45
|
constructor(message) {
|
|
36
46
|
super(message);
|
|
@@ -2,6 +2,7 @@ export declare class ConfigurationService {
|
|
|
2
2
|
private dataDir;
|
|
3
3
|
private promptsDir;
|
|
4
4
|
private commonPromptsDir;
|
|
5
|
+
private commonLibraryDir;
|
|
5
6
|
private userPromptsDir;
|
|
6
7
|
private uploadDir;
|
|
7
8
|
private userConfigDir;
|
|
@@ -19,6 +20,7 @@ export declare class ConfigurationService {
|
|
|
19
20
|
exists(configName: string): boolean;
|
|
20
21
|
getCommonPromptsDir(): string;
|
|
21
22
|
getUserPromptsDir(): string;
|
|
23
|
+
getCommonLibraryDir(): string;
|
|
22
24
|
getUserDataDir(): string;
|
|
23
25
|
getUserId(): string;
|
|
24
26
|
}
|
|
@@ -40,6 +40,7 @@ class ConfigurationService {
|
|
|
40
40
|
dataDir;
|
|
41
41
|
promptsDir;
|
|
42
42
|
commonPromptsDir;
|
|
43
|
+
commonLibraryDir;
|
|
43
44
|
userPromptsDir;
|
|
44
45
|
uploadDir;
|
|
45
46
|
userConfigDir;
|
|
@@ -62,6 +63,10 @@ class ConfigurationService {
|
|
|
62
63
|
if (!fs.existsSync(this.commonPromptsDir)) {
|
|
63
64
|
fs.mkdirSync(this.commonPromptsDir, { recursive: true });
|
|
64
65
|
}
|
|
66
|
+
this.commonLibraryDir = path.resolve(commonDir, 'library');
|
|
67
|
+
if (!fs.existsSync(this.commonLibraryDir)) {
|
|
68
|
+
fs.mkdirSync(this.commonLibraryDir, { recursive: true });
|
|
69
|
+
}
|
|
65
70
|
this.userDataDir = path.resolve(this.dataDir, 'user', this.userId);
|
|
66
71
|
this.userPromptsDir = path.resolve(this.userDataDir, 'prompts');
|
|
67
72
|
if (!fs.existsSync(this.userPromptsDir)) {
|
|
@@ -113,6 +118,9 @@ class ConfigurationService {
|
|
|
113
118
|
getUserPromptsDir() {
|
|
114
119
|
return this.userPromptsDir;
|
|
115
120
|
}
|
|
121
|
+
getCommonLibraryDir() {
|
|
122
|
+
return this.commonLibraryDir;
|
|
123
|
+
}
|
|
116
124
|
getUserDataDir() {
|
|
117
125
|
return this.userDataDir;
|
|
118
126
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { LibraryFile, LibraryPrompt } from '../../../shared/types/app.types';
|
|
2
|
+
export declare class LibraryService {
|
|
3
|
+
private getLibraryDir;
|
|
4
|
+
private assertSafeName;
|
|
5
|
+
private normalizeBaseUrl;
|
|
6
|
+
listLocalPrompts(): LibraryPrompt[];
|
|
7
|
+
listLocalFiles(folder: string): LibraryFile[];
|
|
8
|
+
getLocalFileContent(folder: string, file: string): string;
|
|
9
|
+
private fetchJson;
|
|
10
|
+
listRemotePrompts(baseUrl: string): Promise<LibraryPrompt[]>;
|
|
11
|
+
listRemoteFiles(baseUrl: string, folder: string): Promise<LibraryFile[]>;
|
|
12
|
+
getRemoteFileContent(baseUrl: string, folder: string, file: string): Promise<string>;
|
|
13
|
+
copyFromRemote(baseUrl: string, folder: string, userPromptsDir: string): Promise<void>;
|
|
14
|
+
}
|