@musnows/scriverse 0.5.8 → 0.5.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai.js +355 -70
- package/dist/ai.js.map +1 -1
- package/dist/app.js +48 -37
- package/dist/app.js.map +1 -1
- package/dist/cli-core.js +161 -20
- package/dist/cli-core.js.map +1 -1
- package/dist/database.js +72 -0
- package/dist/database.js.map +1 -1
- package/dist/hybrid-search.js +106 -0
- package/dist/hybrid-search.js.map +1 -0
- package/dist/public/app.js +421 -64
- package/dist/public/display-labels.js +13 -1
- package/dist/public/global-search.d.ts +6 -5
- package/dist/public/global-search.js +44 -3
- package/dist/public/index.html +20 -7
- package/dist/public/race-hierarchy.js +0 -35
- package/dist/public/styles.css +36 -10
- package/dist/public/vditor-line-number-layout.d.ts +14 -0
- package/dist/public/vditor-line-number-layout.js +51 -0
- package/dist/relationship-search.js +21 -2
- package/dist/relationship-search.js.map +1 -1
- package/dist/store.js +137 -5
- package/dist/store.js.map +1 -1
- package/dist/user-auth.js +27 -1
- package/dist/user-auth.js.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
package/dist/app.js
CHANGED
|
@@ -16,6 +16,7 @@ import { Database } from "./database.js";
|
|
|
16
16
|
import { assertSafeDocxArchive } from "./docx-security.js";
|
|
17
17
|
import { TASK_TYPES } from "./domain.js";
|
|
18
18
|
import { AppError } from "./errors.js";
|
|
19
|
+
import { HYBRID_SEARCH_TYPES } from "./hybrid-search.js";
|
|
19
20
|
import { applyImportFileHints, parseNovelText } from "./parser.js";
|
|
20
21
|
import { Store, versionedEntityTypes } from "./store.js";
|
|
21
22
|
import { parsePagination } from "./pagination.js";
|
|
@@ -30,7 +31,7 @@ import { currentRequestActor, runWithRequestActor } from "./request-context.js";
|
|
|
30
31
|
import { APP_VERSION } from "./version.js";
|
|
31
32
|
import { fullWorkModulePermissions, proseReplacementPermissionModules } from "./work-permissions.js";
|
|
32
33
|
import { CollaborationPresence, entityEditorPageKey, presencePageKinds } from "./collaboration-presence.js";
|
|
33
|
-
import { clearSessionCookie, createCliApiScopeMiddleware, createUserSessionMiddleware, createWorkAuthorizationMiddleware, relationshipAnalysisReadModules, setSessionCookie, UserAuthService } from "./user-auth.js";
|
|
34
|
+
import { analysisTaskReadModules, clearSessionCookie, createCliApiScopeMiddleware, createUserSessionMiddleware, createWorkAuthorizationMiddleware, relationshipAnalysisReadModules, setSessionCookie, UserAuthService } from "./user-auth.js";
|
|
34
35
|
const nonEmpty = z.string().trim().min(1);
|
|
35
36
|
const identifier = z.string().trim().min(1).max(200);
|
|
36
37
|
const optionalStrings = z.array(z.string()).optional();
|
|
@@ -239,6 +240,7 @@ const raceSchema = z.object({
|
|
|
239
240
|
settingsSections: knowledgeSectionsSchema.optional(),
|
|
240
241
|
memberIds: z.array(identifier).max(1000).optional()
|
|
241
242
|
}).strict();
|
|
243
|
+
const raceHierarchyScopeSchema = z.enum(["roots", "descendants"]).optional();
|
|
242
244
|
const chapterOutlineSchema = z.object({
|
|
243
245
|
goal: z.string().max(100_000).optional(),
|
|
244
246
|
conflict: z.string().max(100_000).optional(),
|
|
@@ -355,6 +357,8 @@ const workAiSettingsSchema = z.object({
|
|
|
355
357
|
autoRunEnabled: z.boolean().optional(),
|
|
356
358
|
autoRunConcurrency: z.number().int().min(1).max(8).optional(),
|
|
357
359
|
autoRunBatchLimit: z.number().int().min(1).max(200).optional(),
|
|
360
|
+
autoRunDailyTaskLimit: z.number().int().min(0).max(10_000).optional(),
|
|
361
|
+
autoRunFailureThreshold: z.number().int().min(1).max(10).optional(),
|
|
358
362
|
bookSummaryContextPercent: z.number().int().min(1).max(90).optional(),
|
|
359
363
|
contextCompactThreshold: z.number().int().min(50).max(90).optional(),
|
|
360
364
|
agentTools: z.array(z.enum(["story_index", "read_chapters", "grep", "search_story_entities", "read_character_sections"])).max(5).optional()
|
|
@@ -626,11 +630,7 @@ export function createRuntime(options) {
|
|
|
626
630
|
};
|
|
627
631
|
const captcha = new ImageCaptchaService({ revealAnswer: options.revealCaptchaAnswer === true });
|
|
628
632
|
const ai = new AiManager(store, new CredentialVault(options.masterSecret), options.fetchImpl ?? fetch, options.security ? (url) => assertSafeAiEndpoint(url, options.security?.allowPrivateAiEndpoints) : undefined, (task, actor) => {
|
|
629
|
-
|
|
630
|
-
return;
|
|
631
|
-
const requiredModules = relationshipAnalysisReadModules(task.scope);
|
|
632
|
-
if (requiredModules.length === 0)
|
|
633
|
-
return;
|
|
633
|
+
const requiredModules = analysisTaskReadModules(task.taskType, task.scope);
|
|
634
634
|
const creator = actor ? null : database.get("SELECT created_by_user_id FROM analysis_tasks WHERE id = ?", String(task.id));
|
|
635
635
|
const userId = actor?.userId ?? (typeof creator?.created_by_user_id === "string" ? creator.created_by_user_id : null);
|
|
636
636
|
if (!userId)
|
|
@@ -1280,9 +1280,19 @@ export function createRuntime(options) {
|
|
|
1280
1280
|
noContent(response);
|
|
1281
1281
|
});
|
|
1282
1282
|
app.get("/api/works/:workId/races", (request, response) => {
|
|
1283
|
+
const hierarchyScope = parse(raceHierarchyScopeSchema, request.query.scope);
|
|
1283
1284
|
const pagination = parsePagination(request.query);
|
|
1285
|
+
if (hierarchyScope && pagination) {
|
|
1286
|
+
throw new AppError(400, "RACE_HIERARCHY_PAGINATION_CONFLICT", "分层种族请求不能同时使用分页参数");
|
|
1287
|
+
}
|
|
1284
1288
|
const includeMarkdown = request.query.includeContent === "true";
|
|
1285
|
-
const races =
|
|
1289
|
+
const races = hierarchyScope
|
|
1290
|
+
? hierarchyScope === "roots"
|
|
1291
|
+
? { items: store.listRacesByHierarchyScope(request.params.workId, hierarchyScope, includeMarkdown), total: store.countRaces(request.params.workId) }
|
|
1292
|
+
: store.listRacesByHierarchyScope(request.params.workId, hierarchyScope, includeMarkdown)
|
|
1293
|
+
: pagination
|
|
1294
|
+
? store.listRacesPage(request.params.workId, pagination, includeMarkdown)
|
|
1295
|
+
: store.listRaces(request.params.workId, includeMarkdown);
|
|
1286
1296
|
const permissions = requestPermissions(request, request.params.workId);
|
|
1287
1297
|
data(response, mapRecords(races, (race) => redactRaceMembers(race, permissions)));
|
|
1288
1298
|
});
|
|
@@ -1458,6 +1468,7 @@ export function createRuntime(options) {
|
|
|
1458
1468
|
data(response, pagination ? store.listReviewItemsPage(request.params.workId, pagination, status) : store.listReviewItems(request.params.workId, status));
|
|
1459
1469
|
});
|
|
1460
1470
|
app.post("/api/works/:workId/reviews", (request, response) => data(response, store.createReviewItem(request.params.workId, parse(reviewSchema, request.body)), 201));
|
|
1471
|
+
app.get("/api/reviews/:reviewId", (request, response) => data(response, store.getReviewItem(request.params.reviewId)));
|
|
1461
1472
|
app.patch("/api/reviews/:reviewId", (request, response) => data(response, store.updateReviewItem(request.params.reviewId, parse(reviewSchema.partial(), request.body))));
|
|
1462
1473
|
app.post("/api/reviews/:reviewId/character-resolution", (request, response) => {
|
|
1463
1474
|
const input = parse(z.discriminatedUnion("action", [
|
|
@@ -1502,17 +1513,15 @@ export function createRuntime(options) {
|
|
|
1502
1513
|
const permissions = requestPermissions(request, request.params.workId);
|
|
1503
1514
|
for (const taskId of store.listOldestPendingTaskIds(request.params.workId, store.countPendingTasks(request.params.workId))) {
|
|
1504
1515
|
const task = store.getTask(taskId);
|
|
1505
|
-
|
|
1506
|
-
continue;
|
|
1507
|
-
const deniedModules = relationshipAnalysisReadModules(task.scope).filter((module) => permissions[module] === "none");
|
|
1516
|
+
const deniedModules = analysisTaskReadModules(task.taskType, task.scope).filter((module) => permissions[module] === "none");
|
|
1508
1517
|
if (deniedModules.length > 0) {
|
|
1509
|
-
throw new AppError(403, "WORK_MODULE_READ_DENIED", "
|
|
1518
|
+
throw new AppError(403, "WORK_MODULE_READ_DENIED", "你没有读取待运行分析任务所需资料模块的权限", {
|
|
1510
1519
|
taskId,
|
|
1511
1520
|
modules: deniedModules
|
|
1512
1521
|
});
|
|
1513
1522
|
}
|
|
1514
1523
|
}
|
|
1515
|
-
data(response, ai.
|
|
1524
|
+
data(response, ai.resumeAutoRun(request.params.workId));
|
|
1516
1525
|
});
|
|
1517
1526
|
app.get("/api/tasks/:taskId/detail", (request, response) => data(response, redactTaskCharacterNames(store.getTaskDetail(request.params.taskId), requestPermissions(request))));
|
|
1518
1527
|
app.get("/api/tasks/:taskId/result", (request, response) => {
|
|
@@ -1531,14 +1540,12 @@ export function createRuntime(options) {
|
|
|
1531
1540
|
app.post("/api/tasks/:taskId/run", async (request, response) => {
|
|
1532
1541
|
const input = parse(z.object({ modelId: identifier.optional() }), request.body ?? {});
|
|
1533
1542
|
const task = store.getTask(request.params.taskId);
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
});
|
|
1541
|
-
}
|
|
1543
|
+
const permissions = requestPermissions(request, String(task.workId));
|
|
1544
|
+
const deniedModules = analysisTaskReadModules(task.taskType, task.scope).filter((module) => permissions[module] === "none");
|
|
1545
|
+
if (deniedModules.length > 0) {
|
|
1546
|
+
throw new AppError(403, "WORK_MODULE_READ_DENIED", "你没有读取本次分析所需资料模块的权限", {
|
|
1547
|
+
modules: deniedModules
|
|
1548
|
+
});
|
|
1542
1549
|
}
|
|
1543
1550
|
data(response, redactTaskCharacterNames(await ai.runTask(request.params.taskId, input.modelId, request.authUser ? {
|
|
1544
1551
|
userId: request.authUser.userId,
|
|
@@ -1546,18 +1553,16 @@ export function createRuntime(options) {
|
|
|
1546
1553
|
} : undefined), requestPermissions(request)));
|
|
1547
1554
|
});
|
|
1548
1555
|
app.post("/api/tasks/:taskId/rerun", (request, response) => {
|
|
1549
|
-
parse(z.object({}).strict(), request.body ?? {});
|
|
1556
|
+
const input = parse(z.object({ modelId: identifier.optional() }).strict(), request.body ?? {});
|
|
1550
1557
|
const task = store.getTask(request.params.taskId);
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
});
|
|
1558
|
-
}
|
|
1558
|
+
const permissions = requestPermissions(request, String(task.workId));
|
|
1559
|
+
const deniedModules = analysisTaskReadModules(task.taskType, task.scope).filter((module) => permissions[module] === "none");
|
|
1560
|
+
if (deniedModules.length > 0) {
|
|
1561
|
+
throw new AppError(403, "WORK_MODULE_READ_DENIED", "你没有读取本次分析所需资料模块的权限", {
|
|
1562
|
+
modules: deniedModules
|
|
1563
|
+
});
|
|
1559
1564
|
}
|
|
1560
|
-
data(response, redactTaskCharacterNames(ai.rerunTask(request.params.taskId), requestPermissions(request)), 201);
|
|
1565
|
+
data(response, redactTaskCharacterNames(ai.rerunTask(request.params.taskId, input.modelId), requestPermissions(request)), 201);
|
|
1561
1566
|
});
|
|
1562
1567
|
app.post("/api/tasks/:taskId/cancel", (request, response) => data(response, redactTaskCharacterNames(ai.cancelTask(request.params.taskId), requestPermissions(request))));
|
|
1563
1568
|
app.post("/api/tasks/:taskId/relationship-changes/apply", (request, response) => {
|
|
@@ -1615,12 +1620,14 @@ export function createRuntime(options) {
|
|
|
1615
1620
|
});
|
|
1616
1621
|
app.patch("/api/works/:workId/ai-settings", (request, response) => {
|
|
1617
1622
|
const workId = request.params.workId;
|
|
1623
|
+
const input = parse(workAiSettingsSchema, request.body);
|
|
1618
1624
|
const before = store.getWorkAiSettings(workId);
|
|
1619
|
-
|
|
1625
|
+
let updated = store.updateWorkAiSettings(workId, input);
|
|
1620
1626
|
if (updated.autoRunEnabled) {
|
|
1621
|
-
if (!before.autoRunEnabled)
|
|
1622
|
-
ai.
|
|
1623
|
-
|
|
1627
|
+
if (input.autoRunEnabled === true && !before.autoRunEnabled)
|
|
1628
|
+
updated = ai.resumeAutoRun(workId);
|
|
1629
|
+
else
|
|
1630
|
+
ai.scheduleAutoRun(workId);
|
|
1624
1631
|
}
|
|
1625
1632
|
data(response, updated);
|
|
1626
1633
|
});
|
|
@@ -1858,9 +1865,13 @@ export function createRuntime(options) {
|
|
|
1858
1865
|
const pagination = parsePagination(request.query);
|
|
1859
1866
|
data(response, pagination ? ai.listCallsPage(request.params.workId, pagination) : ai.listCalls(request.params.workId));
|
|
1860
1867
|
});
|
|
1861
|
-
app.get("/api/works/:workId/search", (request, response) => {
|
|
1862
|
-
const query = parse(z.
|
|
1863
|
-
|
|
1868
|
+
app.get("/api/works/:workId/search", async (request, response) => {
|
|
1869
|
+
const query = parse(z.object({
|
|
1870
|
+
q: z.string().trim().min(1).max(500),
|
|
1871
|
+
type: z.enum(HYBRID_SEARCH_TYPES).optional(),
|
|
1872
|
+
limit: z.coerce.number().int().min(1).max(100).optional()
|
|
1873
|
+
}).strict(), request.query);
|
|
1874
|
+
data(response, await ai.searchWork(request.params.workId, query.q, { type: query.type, limit: query.limit }));
|
|
1864
1875
|
});
|
|
1865
1876
|
app.get("/api/works/:workId/export", async (request, response) => {
|
|
1866
1877
|
const format = parse(z.enum(["json", "txt", "markdown"]), request.query.format ?? "json");
|