@musnows/scriverse 0.8.5 → 0.8.6

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.
Files changed (48) hide show
  1. package/README.md +1 -0
  2. package/dist/ai-model-pricing.js +295 -0
  3. package/dist/ai-model-pricing.js.map +1 -0
  4. package/dist/ai-protocol.js +335 -15
  5. package/dist/ai-protocol.js.map +1 -1
  6. package/dist/ai-retry.js +1 -1
  7. package/dist/ai-retry.js.map +1 -1
  8. package/dist/ai.js +1073 -138
  9. package/dist/ai.js.map +1 -1
  10. package/dist/app.js +220 -24
  11. package/dist/app.js.map +1 -1
  12. package/dist/attachment-download.js +26 -0
  13. package/dist/attachment-download.js.map +1 -0
  14. package/dist/attachment-storage.js +8 -6
  15. package/dist/attachment-storage.js.map +1 -1
  16. package/dist/cli-contract.js +6 -4
  17. package/dist/cli-contract.js.map +1 -1
  18. package/dist/database.js +306 -3
  19. package/dist/database.js.map +1 -1
  20. package/dist/public/ai-image-attachments.d.ts +21 -0
  21. package/dist/public/ai-image-attachments.js +42 -0
  22. package/dist/public/ai-usage.d.ts +1 -0
  23. package/dist/public/ai-usage.js +11 -0
  24. package/dist/public/app.js +875 -102
  25. package/dist/public/display-labels.d.ts +2 -1
  26. package/dist/public/display-labels.js +6 -6
  27. package/dist/public/index.html +42 -7
  28. package/dist/public/model-config.d.ts +3 -1
  29. package/dist/public/model-config.js +9 -2
  30. package/dist/public/styles.css +111 -6
  31. package/dist/s3-backup.js +21 -0
  32. package/dist/s3-backup.js.map +1 -1
  33. package/dist/security.js +2 -1
  34. package/dist/security.js.map +1 -1
  35. package/dist/server-runtime.js +6 -0
  36. package/dist/server-runtime.js.map +1 -1
  37. package/dist/store.js +550 -44
  38. package/dist/store.js.map +1 -1
  39. package/dist/upload-limits.js +10 -4
  40. package/dist/upload-limits.js.map +1 -1
  41. package/dist/user-auth.js +3 -0
  42. package/dist/user-auth.js.map +1 -1
  43. package/dist/utils.js +1 -1
  44. package/dist/utils.js.map +1 -1
  45. package/dist/version.js +1 -1
  46. package/dist/writing-progress-time.js +15 -0
  47. package/dist/writing-progress-time.js.map +1 -1
  48. package/package.json +1 -1
package/README.md CHANGED
@@ -127,6 +127,7 @@ CLI 会按服务器保存登录凭据。所有连接服务的数据命令都可
127
127
  | `SCRIVERSE_AVATAR_IMAGE_MAX_BYTES` | `2097152` | 头像图片上传大小上限,单位为字节 |
128
128
  | `SCRIVERSE_COVER_IMAGE_MAX_BYTES` | `5242880` | 作品封面图片上传大小上限,单位为字节;封面不支持 GIF |
129
129
  | `SCRIVERSE_ATTACHMENT_IMAGE_MAX_BYTES` | `31457280` | 设定库等其他图片附件上传大小上限,单位为字节;包括 GIF |
130
+ | `SCRIVERSE_AI_CHAT_IMAGE_MAX_BYTES` | `5242880` | 创作助手聊天图片附件上传大小上限,单位为字节;最小可设为 `1048576`(1 MB) |
130
131
 
131
132
  布尔环境变量统一接受 `true`/`1` 表示开启、`false`/`0` 表示关闭;其他数字不会被解析为布尔值。`APP_TRUST_PROXY` 例外,其 `0`–`10` 数字表示可信代理跳数。
132
133
 
@@ -0,0 +1,295 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { chmodSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
3
+ import { dirname } from "node:path";
4
+ import { logger, sanitizeError } from "./logger.js";
5
+ export const LITELLM_MODEL_PRICES_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
6
+ const LITELLM_PRICE_CACHE_VERSION = 1;
7
+ const LITELLM_PRICE_RESPONSE_MAX_BYTES = 8 * 1024 * 1024;
8
+ const LITELLM_PRICE_ENTRY_LIMIT = 20_000;
9
+ const DEFAULT_LITELLM_PRICE_REFRESH_TIMEOUT_MS = 30_000;
10
+ function recordValue(value) {
11
+ return value && typeof value === "object" && !Array.isArray(value)
12
+ ? value
13
+ : null;
14
+ }
15
+ function finiteNonNegative(value) {
16
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
17
+ }
18
+ function normalizedModelId(modelId) {
19
+ return modelId.trim().toLowerCase();
20
+ }
21
+ function optionalPrice(record, key) {
22
+ const value = finiteNonNegative(record[key]);
23
+ return value === null ? undefined : value;
24
+ }
25
+ export function parseLiteLlmPriceTable(payload) {
26
+ const record = recordValue(payload);
27
+ const entries = recordValue(record?.prices) ?? record;
28
+ const table = new Map();
29
+ if (!entries)
30
+ return table;
31
+ for (const [rawModelId, rawPrice] of Object.entries(entries)) {
32
+ if (table.size >= LITELLM_PRICE_ENTRY_LIMIT || rawModelId === "sample_spec")
33
+ continue;
34
+ const modelId = normalizedModelId(rawModelId);
35
+ const priceRecord = recordValue(rawPrice);
36
+ if (!modelId || !priceRecord)
37
+ continue;
38
+ const inputCost = finiteNonNegative(priceRecord.input_cost_per_token);
39
+ const outputCost = finiteNonNegative(priceRecord.output_cost_per_token);
40
+ if (inputCost === null || outputCost === null)
41
+ continue;
42
+ const cacheReadCost = optionalPrice(priceRecord, "cache_read_input_token_cost");
43
+ const legacyCacheReadCost = optionalPrice(priceRecord, "input_cost_per_token_cache_hit");
44
+ const cacheCreationCost = optionalPrice(priceRecord, "cache_creation_input_token_cost");
45
+ table.set(modelId, {
46
+ input_cost_per_token: inputCost,
47
+ output_cost_per_token: outputCost,
48
+ ...(cacheReadCost === undefined ? {} : { cache_read_input_token_cost: cacheReadCost }),
49
+ ...(legacyCacheReadCost === undefined ? {} : { input_cost_per_token_cache_hit: legacyCacheReadCost }),
50
+ ...(cacheCreationCost === undefined ? {} : { cache_creation_input_token_cost: cacheCreationCost })
51
+ });
52
+ }
53
+ return table;
54
+ }
55
+ function serializeLiteLlmPriceTable(table) {
56
+ return Object.fromEntries([...table.entries()].sort(([left], [right]) => left.localeCompare(right)));
57
+ }
58
+ export function nextLiteLlmPriceUpdate(now) {
59
+ const next = new Date(now.getTime());
60
+ next.setHours(24, 0, 0, 0);
61
+ return next;
62
+ }
63
+ export class LiteLlmPriceCache {
64
+ cachePath;
65
+ fetchImpl;
66
+ sourceUrl;
67
+ refreshTimeoutMs;
68
+ schedule;
69
+ now;
70
+ prices = new Map();
71
+ lastSuccessfulUpdateAt = null;
72
+ refreshPromise = null;
73
+ refreshTimer = null;
74
+ activeController = null;
75
+ started = false;
76
+ disposed = false;
77
+ constructor(options = {}) {
78
+ this.cachePath = options.cachePath;
79
+ this.fetchImpl = options.fetchImpl ?? fetch;
80
+ this.sourceUrl = options.sourceUrl ?? LITELLM_MODEL_PRICES_URL;
81
+ this.refreshTimeoutMs = Number.isSafeInteger(options.refreshTimeoutMs) && Number(options.refreshTimeoutMs) > 0
82
+ ? Number(options.refreshTimeoutMs)
83
+ : DEFAULT_LITELLM_PRICE_REFRESH_TIMEOUT_MS;
84
+ this.schedule = options.schedule !== false;
85
+ this.now = options.now ?? (() => new Date());
86
+ this.loadPersistedCache();
87
+ }
88
+ getPriceTable() {
89
+ return this.prices;
90
+ }
91
+ hasData() {
92
+ return this.prices.size > 0;
93
+ }
94
+ start() {
95
+ if (this.started || this.disposed)
96
+ return;
97
+ this.started = true;
98
+ if (this.schedule)
99
+ this.scheduleNextUpdate();
100
+ void this.refresh();
101
+ }
102
+ async refresh() {
103
+ if (this.disposed)
104
+ return false;
105
+ if (this.refreshPromise)
106
+ return this.refreshPromise;
107
+ const refreshPromise = this.fetchAndActivate();
108
+ this.refreshPromise = refreshPromise;
109
+ try {
110
+ return await refreshPromise;
111
+ }
112
+ finally {
113
+ if (this.refreshPromise === refreshPromise)
114
+ this.refreshPromise = null;
115
+ }
116
+ }
117
+ dispose() {
118
+ this.disposed = true;
119
+ if (this.refreshTimer) {
120
+ clearTimeout(this.refreshTimer);
121
+ this.refreshTimer = null;
122
+ }
123
+ this.activeController?.abort();
124
+ this.activeController = null;
125
+ }
126
+ loadPersistedCache() {
127
+ if (!this.cachePath)
128
+ return;
129
+ try {
130
+ const parsed = JSON.parse(readFileSync(this.cachePath, "utf8"));
131
+ const cache = recordValue(parsed);
132
+ const table = parseLiteLlmPriceTable(cache?.prices);
133
+ if (cache?.version !== LITELLM_PRICE_CACHE_VERSION || table.size === 0 || typeof cache.updatedAt !== "string") {
134
+ throw new Error("LiteLLM price cache has an invalid schema");
135
+ }
136
+ this.prices = table;
137
+ this.lastSuccessfulUpdateAt = cache.updatedAt;
138
+ logger.info("ai.litellm_price_cache.loaded", {
139
+ cachePath: this.cachePath,
140
+ modelCount: table.size,
141
+ updatedAt: cache.updatedAt
142
+ });
143
+ }
144
+ catch (error) {
145
+ if (error && typeof error === "object" && "code" in error && error.code === "ENOENT")
146
+ return;
147
+ logger.warn("ai.litellm_price_cache.load_failed", {
148
+ cachePath: this.cachePath,
149
+ error: sanitizeError(error)
150
+ });
151
+ }
152
+ }
153
+ async fetchAndActivate() {
154
+ const controller = new AbortController();
155
+ const timeout = setTimeout(() => controller.abort(), this.refreshTimeoutMs);
156
+ this.activeController = controller;
157
+ try {
158
+ const response = await this.fetchImpl(this.sourceUrl, {
159
+ headers: { accept: "application/json" },
160
+ signal: controller.signal
161
+ });
162
+ if (!response.ok)
163
+ throw new Error(`LiteLLM price response returned HTTP ${response.status}`);
164
+ const body = await response.text();
165
+ if (Buffer.byteLength(body, "utf8") > LITELLM_PRICE_RESPONSE_MAX_BYTES) {
166
+ throw new Error("LiteLLM price response exceeded the size limit");
167
+ }
168
+ let payload;
169
+ try {
170
+ payload = JSON.parse(body);
171
+ }
172
+ catch {
173
+ throw new Error("LiteLLM price response was not valid JSON");
174
+ }
175
+ const nextPrices = parseLiteLlmPriceTable(payload);
176
+ if (nextPrices.size === 0)
177
+ throw new Error("LiteLLM price response contained no valid model prices");
178
+ const updatedAt = this.now().toISOString();
179
+ const cache = {
180
+ version: LITELLM_PRICE_CACHE_VERSION,
181
+ source: this.sourceUrl,
182
+ updatedAt,
183
+ prices: serializeLiteLlmPriceTable(nextPrices)
184
+ };
185
+ this.persistCache(cache);
186
+ this.prices = nextPrices;
187
+ this.lastSuccessfulUpdateAt = updatedAt;
188
+ logger.info("ai.litellm_price_cache.updated", {
189
+ cachePath: this.cachePath ?? "test-only-no-persistence",
190
+ modelCount: nextPrices.size,
191
+ updatedAt
192
+ });
193
+ return true;
194
+ }
195
+ catch (error) {
196
+ if (!this.disposed) {
197
+ logger.warn("ai.litellm_price_cache.refresh_failed", {
198
+ cachePath: this.cachePath ?? "test-only-no-persistence",
199
+ hasHistoricalCache: this.hasData(),
200
+ lastSuccessfulUpdateAt: this.lastSuccessfulUpdateAt,
201
+ error: sanitizeError(error)
202
+ });
203
+ }
204
+ return false;
205
+ }
206
+ finally {
207
+ clearTimeout(timeout);
208
+ if (this.activeController === controller)
209
+ this.activeController = null;
210
+ }
211
+ }
212
+ persistCache(cache) {
213
+ if (!this.cachePath)
214
+ return;
215
+ const directory = dirname(this.cachePath);
216
+ mkdirSync(directory, { recursive: true, mode: 0o700 });
217
+ const temporaryPath = `${this.cachePath}.${randomUUID()}.tmp`;
218
+ try {
219
+ writeFileSync(temporaryPath, JSON.stringify(cache), { encoding: "utf8", mode: 0o600 });
220
+ chmodSync(temporaryPath, 0o600);
221
+ renameSync(temporaryPath, this.cachePath);
222
+ chmodSync(this.cachePath, 0o600);
223
+ }
224
+ catch (error) {
225
+ try {
226
+ unlinkSync(temporaryPath);
227
+ }
228
+ catch {
229
+ // 临时文件清理失败不覆盖真正的写入错误,下一次更新会使用新的临时文件。
230
+ }
231
+ throw error;
232
+ }
233
+ }
234
+ scheduleNextUpdate() {
235
+ if (this.disposed || !this.started || !this.schedule)
236
+ return;
237
+ const current = this.now();
238
+ const next = nextLiteLlmPriceUpdate(current);
239
+ const delayMs = Math.max(1, next.getTime() - current.getTime());
240
+ this.refreshTimer = setTimeout(() => {
241
+ this.refreshTimer = null;
242
+ void this.refresh().finally(() => this.scheduleNextUpdate());
243
+ }, delayMs);
244
+ this.refreshTimer.unref?.();
245
+ logger.info("ai.litellm_price_cache.scheduled", {
246
+ nextUpdateAt: next.toISOString(),
247
+ delayMs
248
+ });
249
+ }
250
+ }
251
+ function usageTokenCount(value) {
252
+ const number = Number(value);
253
+ return Number.isFinite(number) ? Math.max(0, number) : 0;
254
+ }
255
+ function modelPrice(modelId, priceTable) {
256
+ const normalized = normalizedModelId(modelId);
257
+ return normalized ? priceTable.get(normalized) ?? null : null;
258
+ }
259
+ function cacheReadInputTokenPrice(price) {
260
+ return price.cache_read_input_token_cost
261
+ ?? price.input_cost_per_token_cache_hit
262
+ ?? price.input_cost_per_token;
263
+ }
264
+ function cacheCreationInputTokenPrice(price) {
265
+ return price.cache_creation_input_token_cost ?? price.input_cost_per_token;
266
+ }
267
+ export function estimateLiteLlmUsageCost(modelUsages, priceTable = new Map()) {
268
+ let estimatedCost = 0;
269
+ let pricedModelCount = 0;
270
+ let unpricedModelCount = 0;
271
+ for (const usage of modelUsages) {
272
+ const price = modelPrice(usage.modelId, priceTable);
273
+ if (!price) {
274
+ unpricedModelCount += 1;
275
+ continue;
276
+ }
277
+ pricedModelCount += 1;
278
+ const inputTokens = usageTokenCount(usage.inputTokens);
279
+ const outputTokens = usageTokenCount(usage.outputTokens);
280
+ const cachedInputTokens = Math.min(inputTokens, usageTokenCount(usage.cachedInputTokens));
281
+ const cacheWriteInputTokens = Math.min(Math.max(0, inputTokens - cachedInputTokens), usageTokenCount(usage.cacheWriteInputTokens));
282
+ const directInputTokens = Math.max(0, inputTokens - cachedInputTokens - cacheWriteInputTokens);
283
+ estimatedCost += directInputTokens * price.input_cost_per_token;
284
+ estimatedCost += cachedInputTokens * cacheReadInputTokenPrice(price);
285
+ estimatedCost += cacheWriteInputTokens * cacheCreationInputTokenPrice(price);
286
+ estimatedCost += outputTokens * price.output_cost_per_token;
287
+ }
288
+ return {
289
+ estimatedCost: pricedModelCount > 0 || modelUsages.length === 0 ? estimatedCost : null,
290
+ pricedModelCount,
291
+ unpricedModelCount,
292
+ pricingAvailable: priceTable.size > 0
293
+ };
294
+ }
295
+ //# sourceMappingURL=ai-model-pricing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-model-pricing.js","sourceRoot":"","sources":["../src/ai-model-pricing.ts"],"names":[],"mappings":"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"}