@musnows/scriverse 0.5.1 → 0.5.2
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 +438 -147
- package/dist/ai.js.map +1 -1
- package/dist/app.js +89 -13
- package/dist/app.js.map +1 -1
- package/dist/database.js +19 -0
- package/dist/database.js.map +1 -1
- package/dist/public/app.js +111 -45
- package/dist/public/index.html +2 -2
- package/dist/public/styles.css +57 -6
- package/dist/store.js +851 -6
- package/dist/store.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/app.js
CHANGED
|
@@ -358,7 +358,7 @@ const contextSchema = z.object({
|
|
|
358
358
|
});
|
|
359
359
|
const analysisTaskTypeSchema = z.enum(["structure", "chapter-analysis", "character-extraction", "character-summary", "character-identity-audit", "timeline-analysis", "worldview-analysis", "setting-extraction", "consistency-check", "report-update", "book-analysis"]);
|
|
360
360
|
const relationshipAnalysisScopeSchema = z.object({
|
|
361
|
-
type: z.enum(["chapter", "book"]),
|
|
361
|
+
type: z.enum(["chapter", "book", "settings"]),
|
|
362
362
|
chapterId: identifier.optional(),
|
|
363
363
|
includeAllSettings: z.boolean().optional(),
|
|
364
364
|
additionalPrompt: z.string().trim().max(10_000).optional(),
|
|
@@ -434,16 +434,84 @@ function redactRaceMembers(record, permissions) {
|
|
|
434
434
|
function redactOrganizationMembers(record, permissions) {
|
|
435
435
|
return permissions.characters === "none" ? { ...record, memberIds: [], members: [] } : record;
|
|
436
436
|
}
|
|
437
|
+
const taskResultPermissionModules = {
|
|
438
|
+
"chapter-analysis": "prose",
|
|
439
|
+
"character-extraction": "characters",
|
|
440
|
+
"character-summary": "characters",
|
|
441
|
+
"character-identity-audit": "reviews",
|
|
442
|
+
"timeline-analysis": "timeline",
|
|
443
|
+
"relationship-analysis": "relationships",
|
|
444
|
+
"worldview-analysis": "settings",
|
|
445
|
+
"setting-extraction": "settings",
|
|
446
|
+
"consistency-check": "reviews",
|
|
447
|
+
"book-analysis": "prose",
|
|
448
|
+
structure: "outlines",
|
|
449
|
+
"report-update": "prose"
|
|
450
|
+
};
|
|
451
|
+
function requiredTaskResultModule(taskType) {
|
|
452
|
+
return taskResultPermissionModules[String(taskType)];
|
|
453
|
+
}
|
|
437
454
|
function redactTaskCharacterNames(record, permissions) {
|
|
438
455
|
const { scopeSummaryWithoutCharacterNames, ...result } = record;
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
result.scopeSummary
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
456
|
+
const proseRestricted = permissions.prose === "none";
|
|
457
|
+
const proseScope = recordValue(result.scope);
|
|
458
|
+
const selectionScopeRestricted = proseRestricted
|
|
459
|
+
&& (proseScope?.type === "selection" || String(result.scopeSummary ?? "").startsWith("选定内容:"));
|
|
460
|
+
if (selectionScopeRestricted) {
|
|
461
|
+
if (proseScope) {
|
|
462
|
+
const { selection: _selection, ...redactedScope } = proseScope;
|
|
463
|
+
result.scope = redactedScope;
|
|
464
|
+
}
|
|
465
|
+
result.scopeSummary = "选定内容(正文读取权限受限)";
|
|
466
|
+
if (Array.isArray(result.scopeDetails)) {
|
|
467
|
+
result.scopeDetails = result.scopeDetails.map((item) => {
|
|
468
|
+
const detail = recordValue(item);
|
|
469
|
+
return detail?.type === "selection" ? { type: "selection", restricted: true } : item;
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
const characterRestricted = permissions.characters === "none";
|
|
474
|
+
if (characterRestricted) {
|
|
475
|
+
if (!selectionScopeRestricted && typeof scopeSummaryWithoutCharacterNames === "string")
|
|
476
|
+
result.scopeSummary = scopeSummaryWithoutCharacterNames;
|
|
477
|
+
const scope = recordValue(result.scope);
|
|
478
|
+
if (scope) {
|
|
479
|
+
const { targetCharacters: _targetCharacters, ...redactedScope } = scope;
|
|
480
|
+
result.scope = redactedScope;
|
|
481
|
+
}
|
|
482
|
+
const taskResult = recordValue(result.result);
|
|
483
|
+
if (taskResult) {
|
|
484
|
+
const redactedTaskResult = { ...taskResult };
|
|
485
|
+
if (Array.isArray(taskResult.relationshipResults)) {
|
|
486
|
+
redactedTaskResult.relationshipResults = taskResult.relationshipResults.map((value) => {
|
|
487
|
+
const relationship = recordValue(value);
|
|
488
|
+
if (!relationship)
|
|
489
|
+
return value;
|
|
490
|
+
const { fromCharacterName: _fromCharacterName, toCharacterName: _toCharacterName, ...redactedRelationship } = relationship;
|
|
491
|
+
return redactedRelationship;
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
const analysisTarget = recordValue(taskResult.analysisTarget);
|
|
495
|
+
if (analysisTarget) {
|
|
496
|
+
const { characterNames: _characterNames, ...redactedAnalysisTarget } = analysisTarget;
|
|
497
|
+
redactedTaskResult.analysisTarget = redactedAnalysisTarget;
|
|
498
|
+
}
|
|
499
|
+
result.result = redactedTaskResult;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
const resultSummary = recordValue(result.resultSummary);
|
|
503
|
+
const characterSensitiveTask = ["character-extraction", "character-summary", "character-identity-audit", "relationship-analysis"]
|
|
504
|
+
.includes(String(result.taskType));
|
|
505
|
+
const requiredResultModule = requiredTaskResultModule(result.taskType);
|
|
506
|
+
const resultRestricted = requiredResultModule !== undefined && permissions[requiredResultModule] === "none";
|
|
507
|
+
if (resultSummary && (resultRestricted || (characterRestricted && characterSensitiveTask))) {
|
|
508
|
+
result.resultSummary = {
|
|
509
|
+
...resultSummary,
|
|
510
|
+
analysisContent: `${String(resultSummary.title ?? "AI 分析")};范围:${String(result.scopeSummary ?? "未指定")}`,
|
|
511
|
+
summary: "当前账号缺少相关资料的读取权限,无法展示对应的可读结论。",
|
|
512
|
+
sections: [],
|
|
513
|
+
restricted: true
|
|
514
|
+
};
|
|
447
515
|
}
|
|
448
516
|
return result;
|
|
449
517
|
}
|
|
@@ -1354,12 +1422,20 @@ export function createRuntime(options) {
|
|
|
1354
1422
|
app.post("/api/works/:workId/tasks/auto-run", (request, response) => {
|
|
1355
1423
|
data(response, ai.startAutoRunBatch(request.params.workId));
|
|
1356
1424
|
});
|
|
1425
|
+
app.get("/api/tasks/:taskId/detail", (request, response) => data(response, redactTaskCharacterNames(store.getTaskDetail(request.params.taskId), requestPermissions(request))));
|
|
1426
|
+
app.get("/api/tasks/:taskId/result", (request, response) => {
|
|
1427
|
+
const task = store.getTaskResultPayload(request.params.taskId);
|
|
1428
|
+
const permissions = requestPermissions(request);
|
|
1429
|
+
const requiredModule = requiredTaskResultModule(task.taskType);
|
|
1430
|
+
if (requiredModule && permissions[requiredModule] === "none") {
|
|
1431
|
+
throw new AppError(403, "WORK_MODULE_READ_DENIED", "你没有读取该分析结果对应资料模块的权限");
|
|
1432
|
+
}
|
|
1433
|
+
const redacted = redactTaskCharacterNames(task, permissions);
|
|
1434
|
+
data(response, { taskId: task.id, result: redacted.result });
|
|
1435
|
+
});
|
|
1357
1436
|
app.get("/api/tasks/:taskId", (request, response) => data(response, redactTaskCharacterNames(store.getTask(request.params.taskId), requestPermissions(request))));
|
|
1358
1437
|
app.get("/api/tasks/:taskId/trace", (request, response) => data(response, ai.getTaskTrace(request.params.taskId)));
|
|
1359
|
-
app.get("/api/tasks/:taskId/trace/calls/:callId", (request, response) =>
|
|
1360
|
-
const full = parse(z.enum(["true", "false"]).default("false"), request.query.full ?? "false") === "true";
|
|
1361
|
-
data(response, ai.getTaskTraceCall(request.params.taskId, request.params.callId, full));
|
|
1362
|
-
});
|
|
1438
|
+
app.get("/api/tasks/:taskId/trace/calls/:callId", (request, response) => data(response, ai.getTaskTraceCall(request.params.taskId, request.params.callId)));
|
|
1363
1439
|
app.post("/api/tasks/:taskId/run", async (request, response) => {
|
|
1364
1440
|
const input = parse(z.object({ modelId: identifier.optional() }), request.body ?? {});
|
|
1365
1441
|
data(response, redactTaskCharacterNames(await ai.runTask(request.params.taskId, input.modelId), requestPermissions(request)));
|