feat: implement core UI tabs, API backend management, and initial service infrastructure.
This commit is contained in:
+100
-100
@@ -1,402 +1,402 @@
|
||||
[
|
||||
{
|
||||
"name": "Hậu cung",
|
||||
"description": ""
|
||||
"description": "Nhân vật chính (thường là nam) có mối quan hệ tình cảm đồng thời và kết hôn cùng nhiều nhân vật khác giới."
|
||||
},
|
||||
{
|
||||
"name": "1v1",
|
||||
"description": ""
|
||||
"description": "Cốt truyện chỉ xoay quanh tình yêu duy nhất trọn đời giữa hai người, thủy chung 1 nam - 1 nữ."
|
||||
},
|
||||
{
|
||||
"name": "NP",
|
||||
"description": ""
|
||||
"description": "Motif Poly (Multiple Partners), một nhân vật chính có mối quan hệ tình cảm lãng mạn chính thức với nhiều người cùng một lúc và kết thúc có hậu cùng nhau hòa bình."
|
||||
},
|
||||
{
|
||||
"name": "Nữ phẫn nam trang",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Nam phẫn nữ trang",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Xuyên không",
|
||||
"description": ""
|
||||
"description": "Nhân vật chính từ thế giới thực xuyên đến một thế giới khác, thời đại khác."
|
||||
},
|
||||
{
|
||||
"name": "Xuyên sách",
|
||||
"description": ""
|
||||
"description": "Nhân vật chính xuyên vào cốt truyện của một bộ tiểu thuyết, thường thay đổi số phận của nguyên chủ."
|
||||
},
|
||||
{
|
||||
"name": "Trọng sinh",
|
||||
"description": ""
|
||||
"description": "Nhân vật chính chết đi và sống lại ở một thời điểm trong quá khứ để làm lại cuộc đời."
|
||||
},
|
||||
{
|
||||
"name": "Hệ thống",
|
||||
"description": ""
|
||||
"description": "Được gắn kết với một hệ thống (trí tuệ nhân tạo) cung cấp nhiệm vụ, kỹ năng và đạo cụ."
|
||||
},
|
||||
{
|
||||
"name": "Bàn tay vàng",
|
||||
"description": ""
|
||||
"description": "Sở hữu năng lực, bảo bối hoặc lợi thế cực kỳ to lớn ngay từ đầu."
|
||||
},
|
||||
{
|
||||
"name": "Không gian tùy thân",
|
||||
"description": ""
|
||||
"description": "Có một dị không gian bí mật để tàng hình, lưu trữ vật phẩm hoặc trồng trọt."
|
||||
},
|
||||
{
|
||||
"name": "Linh tuyền",
|
||||
"description": ""
|
||||
"description": "Sở hữu suối nước thánh có tác dụng cường thân kiện thể, chữa bách bệnh, thúc đẩy sinh trưởng."
|
||||
},
|
||||
{
|
||||
"name": "Đọc tâm thuật",
|
||||
"description": ""
|
||||
"description": "Năng lực ngoại cảm có thể nghe được suy nghĩ thực sự của người khác."
|
||||
},
|
||||
{
|
||||
"name": "Vô địch lưu",
|
||||
"description": ""
|
||||
"description": "Nhân vật chính sở hữu sức mạnh vô địch, áp đảo mọi kẻ thù ngay từ đầu truyện."
|
||||
},
|
||||
{
|
||||
"name": "Cẩu đạo",
|
||||
"description": ""
|
||||
"description": "Nhân vật chính theo trường phái ẩn nhẫn, phát triển âm thầm, tuyệt đối không phô trương để giấu thực lực."
|
||||
},
|
||||
{
|
||||
"name": "Nhiệt huyết",
|
||||
"description": ""
|
||||
"description": "Mạch truyện sục sôi, đề cao tinh thần chiến đấu không lùi bước, dũng cảm đối mặt rủi ro."
|
||||
},
|
||||
{
|
||||
"name": "Hài hước",
|
||||
"description": ""
|
||||
"description": "Văn phong mang đậm tính giải trí, tấu hài, nhiều tình huống dở khóc dở cười."
|
||||
},
|
||||
{
|
||||
"name": "Sảng văn",
|
||||
"description": ""
|
||||
"description": "Truyện tập trung vào sự thăng tiến nhanh chóng, vả mặt kẻ khinh thường mình, mang lại cảm giác thỏa mãn."
|
||||
},
|
||||
{
|
||||
"name": "Ngọt sủng",
|
||||
"description": ""
|
||||
"description": "Tình tiết lãng mạn, ngọt ngào, nhân vật chính được yêu thương chiều chuộng hết mực, ít bi kịch."
|
||||
},
|
||||
{
|
||||
"name": "Ngược luyến",
|
||||
"description": ""
|
||||
"description": "Tình yêu nhiều oán hận, hiểu lầm, dằn vặt tổn thương sâu sắc cả thể xác lẫn tinh thần."
|
||||
},
|
||||
{
|
||||
"name": "Gương vỡ lại lành",
|
||||
"description": ""
|
||||
"description": "Hai người từng yêu nhau, chia tay vì hiểu lầm hoặc hoàn cảnh, sau đó vượt qua thử thách để quay về bên nhau."
|
||||
},
|
||||
{
|
||||
"name": "Cưới trước yêu sau",
|
||||
"description": ""
|
||||
"description": "Kết hôn vì bổn phận, giao dịch hoặc ép buộc, sau quá trình sống chung mới nảy sinh tình cảm thật sự."
|
||||
},
|
||||
{
|
||||
"name": "Oan gia ngõ hẹp",
|
||||
"description": ""
|
||||
"description": "Cặp đôi ban đầu có ấn tượng xấu, ghét bỏ nhau, nhưng qua nhiều đụng độ lại dần yêu nhau."
|
||||
},
|
||||
{
|
||||
"name": "Thanh mai trúc mã",
|
||||
"description": ""
|
||||
"description": "Nhân vật lớn lên cùng nhau từ nhỏ, có nền tảng tình cảm gắn kết sâu đậm và hiểu rõ về nhau."
|
||||
},
|
||||
{
|
||||
"name": "Hào môn thế gia",
|
||||
"description": ""
|
||||
"description": "Bối cảnh giới siêu giàu, gia tộc quyền thế, đi kèm với tranh giành tài sản hoặc hôn nhân thương mại."
|
||||
},
|
||||
{
|
||||
"name": "Tổng tài",
|
||||
"description": ""
|
||||
"description": "Nam chính là giám đốc, chủ tịch bá đạo, quyền thế, lạnh lùng nhưng rất sủng ái nữ chính."
|
||||
},
|
||||
{
|
||||
"name": "Minh tinh",
|
||||
"description": ""
|
||||
"description": "Nhân vật chính là ngôi sao giải trí, cốt truyện khai thác ánh hào quang và góc khuất của showbiz."
|
||||
},
|
||||
{
|
||||
"name": "Giới giải trí",
|
||||
"description": ""
|
||||
"description": "Bối cảnh tập trung vào mâu thuẫn, lịch trình, scandal và hoạt động nghệ thuật của giới giải trí."
|
||||
},
|
||||
{
|
||||
"name": "Vườn trường",
|
||||
"description": ""
|
||||
"description": "Truyện xoay quanh cuộc sống thanh xuân học đường, tình cảm tuổi học trò trong sáng và nhiệt huyết."
|
||||
},
|
||||
{
|
||||
"name": "Học bá",
|
||||
"description": ""
|
||||
"description": "Nhân vật chính có trí tuệ xuất chúng, tính toán thần sầu, giỏi giang về mặt học vấn."
|
||||
},
|
||||
{
|
||||
"name": "Võng du",
|
||||
"description": ""
|
||||
"description": "Nhân vật chơi game online (có thể là thực tế ảo), cốt truyện đan xen giữa game và đời thực."
|
||||
},
|
||||
{
|
||||
"name": "E-sports",
|
||||
"description": ""
|
||||
"description": "Tập trung vào thể thao điện tử chuyên nghiệp, giải đấu và sự cạnh tranh khốc liệt khao khát cúp vô địch."
|
||||
},
|
||||
{
|
||||
"name": "Livestream",
|
||||
"description": ""
|
||||
"description": "Sử dụng hình thức phát sóng trực tiếp (livestream) để tương tác, kiếm tiền hoặc làm nhiệm vụ."
|
||||
},
|
||||
{
|
||||
"name": "Mỹ thực",
|
||||
"description": ""
|
||||
"description": "Tập trung miêu tả các món ăn ngon, quá trình nấu nướng và kinh doanh nhà hàng xuất sắc."
|
||||
},
|
||||
{
|
||||
"name": "Nông trại",
|
||||
"description": ""
|
||||
"description": "Quản lý và phát triển nông trại, thường kết hợp với kinh tế nhàn nhã, chữa lành."
|
||||
},
|
||||
{
|
||||
"name": "Điền văn",
|
||||
"description": ""
|
||||
"description": "Cốt truyện bình dị, mô tả cuộc sống làm ruộng, làm nông trồng trọt chăn nuôi mang hơi thở dân dã, ấm cúng."
|
||||
},
|
||||
{
|
||||
"name": "Nuôi con",
|
||||
"description": ""
|
||||
"description": "Tập trung vào hành trình chăm sóc, nuôi dưỡng con cái (con ruột, con nuôi hoặc manh bảo)."
|
||||
},
|
||||
{
|
||||
"name": "Làm giàu",
|
||||
"description": ""
|
||||
"description": "Quá trình nhân vật chính từ hai bàn tay trắng xây dựng sự nghiệp, kinh doanh trở nên giàu sang phú quý."
|
||||
},
|
||||
{
|
||||
"name": "Cung đấu",
|
||||
"description": ""
|
||||
"description": "Những mưu mô ác hiểm tranh giành sủng ái và quyền lực chốn hậu cung giữa các phi tần."
|
||||
},
|
||||
{
|
||||
"name": "Gia đấu",
|
||||
"description": ""
|
||||
"description": "Xung đột lợi ích, quyền hành và địa vị nội bộ trong các đại gia tộc danh gia vọng tộc."
|
||||
},
|
||||
{
|
||||
"name": "Quyền mưu",
|
||||
"description": ""
|
||||
"description": "Sử dụng trí mưu, âm mưu quyền thuật thâm sâu để tranh đoạt vương quyền, vị thế trên triều đình."
|
||||
},
|
||||
{
|
||||
"name": "Nữ cường",
|
||||
"description": ""
|
||||
"description": "Nữ chính độc lập, mạnh mẽ, thông minh, không quá luỵ nam chính, thường tự giải quyết các rắc rối mưu mô."
|
||||
},
|
||||
{
|
||||
"name": "Nam cường",
|
||||
"description": ""
|
||||
"description": "Nam chính vô cùng mạnh mẽ, quyền thế, tài giỏi, cường giả vi tôn che chở và bảo vệ người mình yêu."
|
||||
},
|
||||
{
|
||||
"name": "Song khiết",
|
||||
"description": ""
|
||||
"description": "Cả nam và nữ chính đều là mối tình đầu tiên về cả thể xác lẫn tâm hồn của nhau, 1v1 tuyệt đối."
|
||||
},
|
||||
{
|
||||
"name": "Phế Sài",
|
||||
"description": ""
|
||||
"description": "Nhân vật chính bị coi là đồ bỏ đi, rác rưởi, không có tài năng bẩm sinh nhưng sau đó quật khởi vả mặt."
|
||||
},
|
||||
{
|
||||
"name": "Thiên tài",
|
||||
"description": ""
|
||||
"description": "Có năng khiếu phi phàm vượt trội, thiên phú cực cao, tốc độ tu luyện hoặc tiếp thu nhanh hơn bất kỳ ai."
|
||||
},
|
||||
{
|
||||
"name": "Từ hôn",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Linh khí khôi phục",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Mạt thế",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Cơ giáp",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Tinh tế",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "ABO",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Người sói",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Ma cà rồng",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Tây huyễn",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Ma pháp",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Kiếm ma",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Pháp sư",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Giả heo ăn hổ",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Bi kịch",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Chữa lành",
|
||||
"description": ""
|
||||
"description": "Văn phong ấm áp ngọt ngào, nhấn mạnh vào quá trình các nhân vật xoa dịu vết thương lòng hoặc áp lực cuộc sống cho nhau."
|
||||
},
|
||||
{
|
||||
"name": "Hắc ám",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Gothic",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Tâm lý",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Tâm thần phân liệt",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Đa nhân cách",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Trinh thám",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Phá án",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Đạo mộ",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Cương thi",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Quy tắc quái đàm",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Vô hạn lưu",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Mau xuyên",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Thực dân",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Chế tạo",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Lĩnh chúa",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Trồng trọt",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Câu cá",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Nuôi thú",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Pokemon",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Anime",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Harry Potter",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Marvel",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Biển sao",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Truyền thuyết đô thị",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Cổ đại",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Dân quốc",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Thập niên 70",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Thập niên 80",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Thập niên 90",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Dị thế",
|
||||
"description": ""
|
||||
"description": "Xuyên đến một thế giới hoàn toàn khác Trái Đất, với những hệ tư tưởng, ma pháp hay nền văn minh dị thường."
|
||||
},
|
||||
{
|
||||
"name": "Đại lục",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Bộ lạc",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Nguyên thủy",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Tu tiên",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Trả thù",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Pháo hôi",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Vai ác",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Tiên tri",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
},
|
||||
{
|
||||
"name": "Phép thuật",
|
||||
"description": ""
|
||||
"description": "AI sẽ sử dụng quy chuẩn và đặc trưng của thể loại con này để tối ưu hóa tình tiết, bối cảnh và văn phong câu chuyện."
|
||||
}
|
||||
]
|
||||
+103
-16
@@ -20,16 +20,16 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
# Mẫu cài sẵn - lựa chọn kiểu phong phú (các phím được ánh xạ tới ngôn ngữ)
|
||||
def _build_preset_templates():
|
||||
"""Build preset templates from locale"""
|
||||
keys = [
|
||||
"default", "xianxia", "romance", "thriller", "scifi", "wuxia",
|
||||
"palace", "military", "historical", "supernatural", "campus",
|
||||
"business", "cyberpunk", "fantasy", "horror", "humor", "literary", "adventure"
|
||||
]
|
||||
return {t(f"templates.name_{k}"): t(f"templates.{k}") for k in keys}
|
||||
"""Build preset templates from StyleManager"""
|
||||
from services.style_manager import StyleManager
|
||||
styles = StyleManager.load_styles()
|
||||
templates = {}
|
||||
for g in styles:
|
||||
templates[g["name"]] = g["description"]
|
||||
return templates
|
||||
|
||||
def get_preset_templates():
|
||||
"""Get preset templates (rebuilt each call to respect active language)"""
|
||||
"""Get preset templates (rebuilt each call to respect Active Genres)"""
|
||||
return _build_preset_templates()
|
||||
|
||||
|
||||
@@ -375,7 +375,8 @@ class NovelGenerator:
|
||||
sub_genres: List[str] = None,
|
||||
previous_content: str = "",
|
||||
context_summary: str = "",
|
||||
custom_prompt: str = ""
|
||||
custom_prompt: str = "",
|
||||
use_reflection: bool = False
|
||||
) -> Tuple[str, str]:
|
||||
"""
|
||||
Tạo một chương đơn lẻ
|
||||
@@ -460,6 +461,22 @@ class NovelGenerator:
|
||||
logger.error(f"Chapter generation failed: {content}")
|
||||
return "", content
|
||||
|
||||
if use_reflection:
|
||||
logger.info("Applying self-reflection to the generated chapter draft...")
|
||||
# Sử dụng content nháp làm nguyên liệu cho lượt tạo reflection mới
|
||||
reflection_sys = t("prompts.reflection_system")
|
||||
reflection_prompt = t("prompts.reflection_user", chapter_req=prompt, draft_content=content, target_words=target_words)
|
||||
reflection_messages = [
|
||||
{"role": "system", "content": reflection_sys},
|
||||
{"role": "user", "content": reflection_prompt}
|
||||
]
|
||||
success, final_content = self.api_client.generate(reflection_messages, use_cache=False)
|
||||
if not success:
|
||||
logger.error(f"Reflection generation failed: {final_content}. Falling back to draft content.")
|
||||
else:
|
||||
logger.info("Reflection generation success.")
|
||||
content = final_content
|
||||
|
||||
logger.info(f"Chapter generation success: {chapter_num}")
|
||||
logger.info(f"Chapter content length: {len(content)}")
|
||||
return content, t("generator.gen_success")
|
||||
@@ -477,7 +494,8 @@ class NovelGenerator:
|
||||
sub_genres: List[str] = None,
|
||||
previous_content: str = "",
|
||||
context_summary: str = "",
|
||||
custom_prompt: str = ""
|
||||
custom_prompt: str = "",
|
||||
use_reflection: bool = False
|
||||
):
|
||||
"""
|
||||
Tạo một chương đơn lẻ bằng streaming
|
||||
@@ -536,13 +554,34 @@ class NovelGenerator:
|
||||
if context_summary:
|
||||
logger.info(f"Using context enhancement, context length: {len(context_summary)}")
|
||||
|
||||
for success, chunk in self.api_client.generate_stream(messages=messages):
|
||||
yield success, chunk
|
||||
if not use_reflection:
|
||||
for success, chunk in self.api_client.generate_stream(messages=messages):
|
||||
yield success, chunk
|
||||
else:
|
||||
logger.info("Generating draft for reflection in streaming mode...")
|
||||
success, draft_content = self.api_client.generate(messages, use_cache=False)
|
||||
|
||||
if not success:
|
||||
logger.error(f"Draft generation failed: {draft_content}")
|
||||
yield False, draft_content
|
||||
return
|
||||
|
||||
logger.info("Draft generated. Applying self-reflection stream...")
|
||||
reflection_sys = t("prompts.reflection_system")
|
||||
reflection_prompt = t("prompts.reflection_user", chapter_req=prompt, draft_content=draft_content, target_words=target_words)
|
||||
reflection_messages = [
|
||||
{"role": "system", "content": reflection_sys},
|
||||
{"role": "user", "content": reflection_prompt}
|
||||
]
|
||||
|
||||
for success, chunk in self.api_client.generate_stream(messages=reflection_messages):
|
||||
yield success, chunk
|
||||
|
||||
def rewrite_paragraph(
|
||||
self,
|
||||
text: str,
|
||||
style_template: str = ""
|
||||
style_template: str = "",
|
||||
use_reflection: bool = False
|
||||
) -> Tuple[str, str]:
|
||||
"""
|
||||
Viết lại đoạn văn (có cơ chế thử lại)
|
||||
@@ -617,6 +656,19 @@ class NovelGenerator:
|
||||
# Xác minh nội dung đã được thông qua
|
||||
logger.info(f"Rewrite done, content length: {len(content)}, attempts: {attempt + 1}")
|
||||
logger.debug(f"Content first 200: {content[:200]}")
|
||||
|
||||
if use_reflection:
|
||||
logger.info("Applying self-reflection to rewritten paragraph draft...")
|
||||
reflection_sys = t("prompts.reflection_system")
|
||||
reflection_prompt = t("prompts.reflection_user", chapter_req=prompt, draft_content=content, target_words=len(content))
|
||||
reflection_messages = [
|
||||
{"role": "system", "content": reflection_sys},
|
||||
{"role": "user", "content": reflection_prompt}
|
||||
]
|
||||
success, final_content = self.api_client.generate(reflection_messages, use_cache=False)
|
||||
if success:
|
||||
content = final_content
|
||||
|
||||
return content, t("generator.rewrite_success")
|
||||
|
||||
# Tất cả các lần thử lại đều thất bại
|
||||
@@ -653,7 +705,8 @@ class NovelGenerator:
|
||||
self,
|
||||
text: str,
|
||||
polish_type: str = "general",
|
||||
custom_requirements: str = ""
|
||||
custom_requirements: str = "",
|
||||
use_reflection: bool = False
|
||||
) -> Tuple[str, str]:
|
||||
"""
|
||||
Văn bản tiếng Ba Lan (với cơ chế thử lại)
|
||||
@@ -746,6 +799,19 @@ class NovelGenerator:
|
||||
# Xác minh nội dung đã được thông qua
|
||||
logger.info(f"Polish done, content length: {len(content)}, attempts: {attempt + 1}")
|
||||
logger.debug(f"Content first 200: {content[:200]}")
|
||||
|
||||
if use_reflection:
|
||||
logger.info("Applying self-reflection to polished paragraph draft...")
|
||||
reflection_sys = t("prompts.reflection_system")
|
||||
reflection_prompt = t("prompts.reflection_user", chapter_req=prompt, draft_content=content, target_words=len(content))
|
||||
reflection_messages = [
|
||||
{"role": "system", "content": reflection_sys},
|
||||
{"role": "user", "content": reflection_prompt}
|
||||
]
|
||||
success, final_content = self.api_client.generate(reflection_messages, use_cache=False)
|
||||
if success:
|
||||
content = final_content
|
||||
|
||||
return content, t("generator.polish_success")
|
||||
|
||||
# Tất cả các lần thử lại đều thất bại
|
||||
@@ -755,7 +821,8 @@ class NovelGenerator:
|
||||
def polish_and_suggest(
|
||||
self,
|
||||
text: str,
|
||||
custom_requirements: str = ""
|
||||
custom_requirements: str = "",
|
||||
use_reflection: bool = False
|
||||
) -> Tuple[str, str, str]:
|
||||
"""
|
||||
Trau chuốt văn bản và đưa ra đề xuất
|
||||
@@ -784,6 +851,18 @@ class NovelGenerator:
|
||||
logger.error(f"Polish failed: {content}")
|
||||
return "", "", content
|
||||
|
||||
if use_reflection:
|
||||
logger.info("Applying self-reflection to polish and suggest paragraph draft...")
|
||||
reflection_sys = t("prompts.reflection_system")
|
||||
reflection_prompt = t("prompts.reflection_user", chapter_req=prompt, draft_content=content, target_words=len(content))
|
||||
reflection_messages = [
|
||||
{"role": "system", "content": reflection_sys},
|
||||
{"role": "user", "content": reflection_prompt}
|
||||
]
|
||||
success, final_content = self.api_client.generate(reflection_messages, use_cache=False)
|
||||
if success:
|
||||
content = final_content
|
||||
|
||||
# Thêm xác minh nội dung
|
||||
if len(content) < 10:
|
||||
logger.warning(f"Polish content too short: {len(content)}, content: {content}")
|
||||
@@ -995,9 +1074,17 @@ class NovelGenerator:
|
||||
|
||||
def _build_style_description(self) -> str:
|
||||
"""Mô tả phong cách xây dựng"""
|
||||
from services.style_manager import StyleManager
|
||||
gen = self.config.generation
|
||||
style_name = gen.writing_style
|
||||
style_desc = StyleManager.get_style_description(style_name)
|
||||
|
||||
full_style = style_name
|
||||
if style_desc:
|
||||
full_style += f" ({style_desc})"
|
||||
|
||||
return t("prompts.style_description",
|
||||
writing_style=gen.writing_style,
|
||||
writing_style=full_style,
|
||||
writing_tone=gen.writing_tone,
|
||||
character_development=gen.character_development,
|
||||
plot_complexity=gen.plot_complexity
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
import os
|
||||
import json
|
||||
import logging
|
||||
from typing import Dict, List, Optional
|
||||
from locales.i18n import t
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
STYLES_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "data", "writing_styles.json")
|
||||
|
||||
class StyleManager:
|
||||
"""Quản lý các phong cách viết truyện và mô tả"""
|
||||
|
||||
_cached_styles = None
|
||||
_cached_mtime = 0
|
||||
|
||||
@classmethod
|
||||
def get_default_styles(cls) -> List[Dict[str, str]]:
|
||||
"""Lấy danh sách phong cách viết mặc định nếu chưa có file"""
|
||||
return [
|
||||
{
|
||||
"name": "Mượt mà tự nhiên, cốt truyện chặt chẽ, nhân vật tinh tế",
|
||||
"description": "Văn phong trơn tru, dễ đọc, mạch truyện logic xuyên suốt không có sạn. Xây dựng tâm lý và hành động nhân vật sâu sắc, nhất quán."
|
||||
},
|
||||
{
|
||||
"name": "Văn phong đẹp, ý cảnh sâu xa",
|
||||
"description": "Sử dụng từ ngữ trau chuốt, giàu hình ảnh và các phép tu từ. Tập trung miêu tả cảnh vật, nội tâm nhân vật để tạo ra một không gian nghệ thuật đầy cảm xúc."
|
||||
},
|
||||
{
|
||||
"name": "Nhịp nhanh, cốt truyện kịch tính",
|
||||
"description": "Tập trung vào hành động, xung đột và diễn biến câu chuyện. Cắt giảm tối đa miêu tả thừa thãi, đưa người đọc đi từ bất ngờ này đến bất ngờ khác."
|
||||
},
|
||||
{
|
||||
"name": "Mô tả tinh tế, cảm xúc phong phú",
|
||||
"description": "Chú trọng vào việc thể hiện cảm xúc, rung động tinh vi của nhân vật. Các chi tiết nhỏ trong bối cảnh và tương tác được dùng để tô đậm không khí truyện."
|
||||
},
|
||||
{
|
||||
"name": "Hài hước thú vị, nhẹ nhàng vui vẻ",
|
||||
"description": "Sử dụng ngôn ngữ hóm hỉnh, tình huống hài hước dở khóc dở cười. Xoay quanh những mẩu chuyện đời thường hoặc hành trình nhẹ nhàng mang tính giải trí cao."
|
||||
}
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def ensure_data_dir(cls):
|
||||
"""Đảm bảo thư mục data tồn tại"""
|
||||
os.makedirs(os.path.dirname(STYLES_FILE), exist_ok=True)
|
||||
|
||||
@classmethod
|
||||
def load_styles(cls) -> List[Dict[str, str]]:
|
||||
"""Tải danh sách phong cách từ file (có cache theo mtime)"""
|
||||
cls.ensure_data_dir()
|
||||
if not os.path.exists(STYLES_FILE):
|
||||
default_styles = cls.get_default_styles()
|
||||
cls.save_styles(default_styles)
|
||||
return default_styles
|
||||
|
||||
try:
|
||||
current_mtime = os.path.getmtime(STYLES_FILE)
|
||||
if cls._cached_styles is not None and cls._cached_mtime == current_mtime:
|
||||
return cls._cached_styles
|
||||
|
||||
with open(STYLES_FILE, 'r', encoding='utf-8') as f:
|
||||
styles = json.load(f)
|
||||
cls._cached_styles = styles
|
||||
cls._cached_mtime = current_mtime
|
||||
return styles
|
||||
except Exception as e:
|
||||
logger.error(f"Error loading styles: {e}")
|
||||
return cls.get_default_styles()
|
||||
|
||||
@classmethod
|
||||
def save_styles(cls, styles: List[Dict[str, str]]) -> bool:
|
||||
"""Lưu danh sách phong cách xuống file"""
|
||||
cls.ensure_data_dir()
|
||||
try:
|
||||
with open(STYLES_FILE, 'w', encoding='utf-8') as f:
|
||||
json.dump(styles, f, ensure_ascii=False, indent=4)
|
||||
# Invalidate cache
|
||||
cls._cached_styles = styles
|
||||
cls._cached_mtime = os.path.getmtime(STYLES_FILE)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Error saving styles: {e}")
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def add_style(cls, name: str, description: str = "") -> bool:
|
||||
"""Thêm một phong cách mới"""
|
||||
styles = cls.load_styles()
|
||||
# Kiểm tra trùng tên
|
||||
if any(g["name"] == name for g in styles):
|
||||
return False
|
||||
|
||||
styles.append({"name": name, "description": description})
|
||||
return cls.save_styles(styles)
|
||||
|
||||
@classmethod
|
||||
def update_style(cls, old_name: str, new_name: str, description: str) -> bool:
|
||||
"""Cập nhật thông tin phong cách"""
|
||||
styles = cls.load_styles()
|
||||
for i, g in enumerate(styles):
|
||||
if g["name"] == old_name:
|
||||
# Nếu đổi tên, kiểm tra trùng tên mới
|
||||
if old_name != new_name and any(x["name"] == new_name for x in styles):
|
||||
return False
|
||||
|
||||
styles[i] = {"name": new_name, "description": description}
|
||||
return cls.save_styles(styles)
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def delete_style(cls, name: str) -> bool:
|
||||
"""Xóa phong cách"""
|
||||
styles = cls.load_styles()
|
||||
initial_length = len(styles)
|
||||
styles = [g for g in styles if g["name"] != name]
|
||||
|
||||
if len(styles) < initial_length:
|
||||
return cls.save_styles(styles)
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def get_style_names(cls) -> List[str]:
|
||||
"""Lấy danh sách tên phong cách để hiển thị UI"""
|
||||
styles = cls.load_styles()
|
||||
return [g["name"] for g in styles]
|
||||
|
||||
@classmethod
|
||||
def get_style_description(cls, name: str) -> str:
|
||||
"""Lấy mô tả hướng dẫn của một phong cách"""
|
||||
styles = cls.load_styles()
|
||||
for g in styles:
|
||||
if g["name"] == name:
|
||||
return g["description"]
|
||||
return ""
|
||||
Reference in New Issue
Block a user