@musnows/scriverse 1.0.8 → 1.0.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/README.en.md +2 -2
- package/README.md +2 -2
- package/dist/ai.js +8 -89
- package/dist/ai.js.map +1 -1
- package/dist/app.js +41 -44
- package/dist/app.js.map +1 -1
- package/dist/public/app.js +176 -133
- package/dist/public/index.html +3 -3
- package/dist/public/styles.css +17 -25
- package/dist/security.js +2 -2
- package/dist/security.js.map +1 -1
- package/dist/server-runtime.js +3 -1
- package/dist/server-runtime.js.map +1 -1
- package/dist/skills/continue-writing/SKILL.md +2 -2
- package/dist/skills/polish-writing/SKILL.md +2 -2
- package/dist/user-auth.js +0 -3
- 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
|
@@ -1111,6 +1111,18 @@ function redactSuggestion(record, permissions) {
|
|
|
1111
1111
|
restricted: true
|
|
1112
1112
|
};
|
|
1113
1113
|
}
|
|
1114
|
+
function redactAiConversationInlineReferences(content, permissions) {
|
|
1115
|
+
const source = typeof content === "string" ? content : "";
|
|
1116
|
+
return source.replace(/<ai_reference kind="(character|setting|chapter|context-settings)" id="[^"]+">[\s\S]*?<\/ai_reference>/gu, (reference, kind) => {
|
|
1117
|
+
const readable = ({
|
|
1118
|
+
character: permissions.characters !== "none",
|
|
1119
|
+
setting: permissions.settings !== "none",
|
|
1120
|
+
chapter: permissions.prose !== "none",
|
|
1121
|
+
"context-settings": permissions.settings !== "none"
|
|
1122
|
+
})[kind] ?? false;
|
|
1123
|
+
return readable ? reference : "(已隐藏引用)";
|
|
1124
|
+
});
|
|
1125
|
+
}
|
|
1114
1126
|
function redactAiConversationMessage(item, permissions) {
|
|
1115
1127
|
const message = recordValue(item);
|
|
1116
1128
|
if (!message)
|
|
@@ -1130,9 +1142,10 @@ function redactAiConversationMessage(item, permissions) {
|
|
|
1130
1142
|
delete readableMetadata.mentionSettingIds;
|
|
1131
1143
|
if (permissions.settings === "none")
|
|
1132
1144
|
delete readableMetadata.mentionContextSettingIds;
|
|
1133
|
-
|
|
1145
|
+
const content = redactAiConversationInlineReferences(message.content, permissions);
|
|
1146
|
+
if (Object.keys(readableMetadata).length === Object.keys(metadata).length && content === message.content)
|
|
1134
1147
|
return item;
|
|
1135
|
-
return { ...message, metadata: readableMetadata };
|
|
1148
|
+
return { ...message, content, metadata: readableMetadata };
|
|
1136
1149
|
}
|
|
1137
1150
|
return {
|
|
1138
1151
|
...message,
|
|
@@ -1387,9 +1400,14 @@ export function createRuntime(options) {
|
|
|
1387
1400
|
});
|
|
1388
1401
|
if (!options.liteLlmPriceCache && options.liteLlmPriceCachePath)
|
|
1389
1402
|
liteLlmPriceCache.start();
|
|
1390
|
-
const
|
|
1403
|
+
const disableAiEndpointValidation = options.developmentServer === true || options.disableAiEndpointValidation === true;
|
|
1404
|
+
const validateAiEndpoint = disableAiEndpointValidation || options.disableAiProviderEndpointValidation === true
|
|
1391
1405
|
? undefined
|
|
1392
|
-
: options.security ? (url) => assertSafeAiEndpoint(url, options.security?.allowPrivateAiEndpoints) : undefined
|
|
1406
|
+
: options.security ? (url) => assertSafeAiEndpoint(url, options.security?.allowPrivateAiEndpoints) : undefined;
|
|
1407
|
+
const validateRemoteMcpEndpoint = disableAiEndpointValidation
|
|
1408
|
+
? undefined
|
|
1409
|
+
: options.security ? (url) => assertSafeAiEndpoint(url, options.security?.allowPrivateAiEndpoints) : undefined;
|
|
1410
|
+
const ai = new AiManager(store, credentialVault, options.fetchImpl ?? fetch, validateAiEndpoint, (task, actor) => {
|
|
1393
1411
|
const requiredModules = analysisTaskReadModules(task.taskType, task.scope);
|
|
1394
1412
|
const creator = actor ? null : database.get("SELECT created_by_user_id, created_via_api_key FROM analysis_tasks WHERE id = ?", String(task.id));
|
|
1395
1413
|
const userId = actor?.userId ?? (typeof creator?.created_by_user_id === "string" ? creator.created_by_user_id : null);
|
|
@@ -1408,6 +1426,7 @@ export function createRuntime(options) {
|
|
|
1408
1426
|
retrySleep: options.aiRetrySleep,
|
|
1409
1427
|
aiChatImageMaxBytes: uploadLimits.chatImageBytes,
|
|
1410
1428
|
liteLlmPriceCache,
|
|
1429
|
+
remoteMcpValidateOutboundUrl: validateRemoteMcpEndpoint,
|
|
1411
1430
|
allowPrivateAiEndpoints: options.security?.allowPrivateAiEndpoints === true
|
|
1412
1431
|
});
|
|
1413
1432
|
const imOrchestrator = new ImOrchestrator(store, auth, im, ai);
|
|
@@ -4034,15 +4053,6 @@ export function createRuntime(options) {
|
|
|
4034
4053
|
}
|
|
4035
4054
|
if (begun.request.status === "completed" && begun.assistantMessage) {
|
|
4036
4055
|
const content = String(begun.assistantMessage.content ?? "");
|
|
4037
|
-
const assistantMetadata = begun.assistantMessage.metadata && typeof begun.assistantMessage.metadata === "object"
|
|
4038
|
-
? begun.assistantMessage.metadata
|
|
4039
|
-
: {};
|
|
4040
|
-
const writingSuggestionId = typeof assistantMetadata.writingSuggestionId === "string"
|
|
4041
|
-
? assistantMetadata.writingSuggestionId
|
|
4042
|
-
: "";
|
|
4043
|
-
const writingSuggestion = writingSuggestionId
|
|
4044
|
-
? redactSuggestion(ai.getSuggestion(writingSuggestionId), permissions)
|
|
4045
|
-
: null;
|
|
4046
4056
|
if (content)
|
|
4047
4057
|
sendEvent("delta", { delta: content, replayed: true });
|
|
4048
4058
|
sendEvent("complete", {
|
|
@@ -4050,8 +4060,7 @@ export function createRuntime(options) {
|
|
|
4050
4060
|
conversationId,
|
|
4051
4061
|
conversationTitle: store.getAiConversationSummary(conversationId).title,
|
|
4052
4062
|
messageId: begun.assistantMessage.id,
|
|
4053
|
-
messageCreatedAt: begun.assistantMessage.createdAt
|
|
4054
|
-
...(writingSuggestion ? { writingSuggestion } : {})
|
|
4063
|
+
messageCreatedAt: begun.assistantMessage.createdAt
|
|
4055
4064
|
});
|
|
4056
4065
|
}
|
|
4057
4066
|
else {
|
|
@@ -4083,7 +4092,7 @@ export function createRuntime(options) {
|
|
|
4083
4092
|
questionId: pendingQuestion.id
|
|
4084
4093
|
});
|
|
4085
4094
|
}
|
|
4086
|
-
const
|
|
4095
|
+
const result = await ai.createStreamingChat({
|
|
4087
4096
|
workId: request.params.workId,
|
|
4088
4097
|
instruction: resolvedInstruction,
|
|
4089
4098
|
skillInstruction: instructionText,
|
|
@@ -4101,33 +4110,30 @@ export function createRuntime(options) {
|
|
|
4101
4110
|
...(input.parameters ? { parameters: input.parameters } : {}),
|
|
4102
4111
|
...(preparedChatImageAttachments.length ? { imageAttachments: preparedChatImageAttachments } : {})
|
|
4103
4112
|
}, (delta) => sendEvent("delta", { delta }));
|
|
4104
|
-
const assistantMessageId = typeof
|
|
4105
|
-
? String(
|
|
4113
|
+
const assistantMessageId = typeof result.conversationMessage === "object" && result.conversationMessage !== null
|
|
4114
|
+
? String(result.conversationMessage.id ?? "")
|
|
4106
4115
|
: "";
|
|
4107
4116
|
if (!stopping) {
|
|
4108
4117
|
store.finishAiConversationStreamRequest(streamRequestId, "completed", "completed", assistantMessageId || undefined);
|
|
4109
4118
|
}
|
|
4110
4119
|
streamRequestFinished = true;
|
|
4111
4120
|
sendEvent("complete", {
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
processSteps: suggestion.processSteps,
|
|
4122
|
-
contextUsage: suggestion.contextUsage,
|
|
4121
|
+
callId: result.callId,
|
|
4122
|
+
provider: result.provider,
|
|
4123
|
+
model: result.model,
|
|
4124
|
+
outputTokens: result.outputTokens,
|
|
4125
|
+
cacheHitPercent: result.cacheHitPercent,
|
|
4126
|
+
processDurationMs: result.processDurationMs,
|
|
4127
|
+
toolCalls: result.toolCalls,
|
|
4128
|
+
processSteps: result.processSteps,
|
|
4129
|
+
contextUsage: result.contextUsage,
|
|
4123
4130
|
conversationId,
|
|
4124
|
-
conversationTitle:
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
? suggestion.conversationMessage.id
|
|
4131
|
+
conversationTitle: result.conversationTitle,
|
|
4132
|
+
messageId: typeof result.conversationMessage === "object" && result.conversationMessage !== null
|
|
4133
|
+
? result.conversationMessage.id
|
|
4128
4134
|
: undefined,
|
|
4129
|
-
messageCreatedAt: typeof
|
|
4130
|
-
?
|
|
4135
|
+
messageCreatedAt: typeof result.conversationMessage === "object" && result.conversationMessage !== null
|
|
4136
|
+
? result.conversationMessage.createdAt
|
|
4131
4137
|
: undefined
|
|
4132
4138
|
});
|
|
4133
4139
|
}
|
|
@@ -4183,15 +4189,6 @@ export function createRuntime(options) {
|
|
|
4183
4189
|
const permissions = requestPermissions(request, String(suggestion.workId));
|
|
4184
4190
|
data(response, redactContinuationGuard(await ai.runSuggestionGuard(request.params.suggestionId, input.content), permissions), 201);
|
|
4185
4191
|
});
|
|
4186
|
-
app.post("/api/suggestions/:suggestionId/accept", (request, response) => {
|
|
4187
|
-
const input = parse(z.object({ content: z.string().max(2_000_000).optional() }), request.body ?? {});
|
|
4188
|
-
const suggestion = ai.getSuggestion(request.params.suggestionId);
|
|
4189
|
-
const permissions = requestPermissions(request, String(suggestion.workId));
|
|
4190
|
-
if (!canWriteWorkModule(permissions, "prose")) {
|
|
4191
|
-
throw new AppError(403, "WORK_MODULE_WRITE_DENIED", "你没有将 AI 建议写入正文的权限");
|
|
4192
|
-
}
|
|
4193
|
-
data(response, ai.acceptSuggestion(request.params.suggestionId, input.content));
|
|
4194
|
-
});
|
|
4195
4192
|
app.post("/api/suggestions/:suggestionId/reject", (request, response) => {
|
|
4196
4193
|
const suggestion = ai.rejectSuggestion(request.params.suggestionId);
|
|
4197
4194
|
const permissions = requestPermissions(request, String(suggestion.workId));
|