@musnows/scriverse 0.7.7 → 0.7.8

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.
@@ -379,7 +379,7 @@ input[type="checkbox"][hidden] { display: none; }
379
379
  }
380
380
 
381
381
  .brand-block { display: flex; align-items: center; gap: 11px; padding: 0 20px; border: 0; background: transparent; text-align: left; }
382
- .brand-mark { display: grid; place-items: center; width: 34px; height: 34px; color: #fff; background: var(--accent); border-radius: 3px; font-weight: 700; }
382
+ .brand-mark { display: grid; place-items: center; width: 34px; height: 34px; color: #fff; border-radius: 3px; font-weight: 700; }
383
383
  .brand-block strong, .brand-block small { display: block; }
384
384
  .brand-block strong { font-size: 16px; letter-spacing: .16em; }
385
385
  .brand-block small { color: var(--muted); font-size: 10px; margin-top: 2px; }
@@ -2796,11 +2796,14 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
2796
2796
  .large-dialog { width: min(1120px, 94vw); max-height: 94dvh; }
2797
2797
  .large-dialog .dialog-fields { max-height: 72dvh; padding: 24px 28px; }
2798
2798
  .editor-dialog { width: min(1180px, 94vw); max-height: calc(100dvh - 16px); }
2799
- .editor-dialog .dialog-fields { grid-template-columns: repeat(2, minmax(0, 1fr)); max-height: 76dvh; padding: 24px 28px; }
2799
+ .editor-dialog .dialog-fields { grid-template-columns: repeat(2, minmax(0, 1fr)); max-height: min(76dvh, calc(100dvh - 214px)); padding: 24px 28px; }
2800
2800
  .editor-dialog .dialog-fields > .form-field-note, .editor-dialog .dialog-fields > .markdown-editor-field { grid-column: 1 / -1; }
2801
2801
  .dialog::backdrop { background: rgba(34,30,25,.42); backdrop-filter: blur(3px); }
2802
2802
  .dialog-header { display: flex; justify-content: space-between; align-items: flex-start; padding: 22px 24px 16px; border-bottom: 1px solid var(--line); }
2803
2803
  .dialog-header h2 { margin: 0; font-size: 23px; font-weight: 500; }
2804
+ .dialog-title-input { display: block; width: min(560px, calc(100vw - 150px)); min-width: 0; margin: -5px 0 0; padding: 0 0 4px; border: 0; border-bottom: 1px solid var(--line); border-radius: 0; background: transparent; color: var(--ink); font-size: 23px; font-weight: 500; line-height: 1.3; }
2805
+ .dialog-title-input:focus { border-bottom-color: var(--accent); outline: none; }
2806
+ .dialog-title-input::placeholder { color: var(--muted); opacity: .8; }
2804
2807
  .dialog-header-meta { margin: 7px 0 0; color: var(--muted); font-size: 10px; line-height: 1.5; }
2805
2808
  .dialog-close {
2806
2809
  display: grid;
@@ -3109,10 +3112,10 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
3109
3112
  .vditor-editor-host .vditor-toolbar { display: flex; align-items: center; flex: 0 0 auto; }
3110
3113
  .vditor-editor-host .markdown-word-count { display: inline-flex; align-items: center; align-self: center; min-height: 28px; margin-left: 24px; padding: 0 10px; color: var(--muted); font: 10px/1 var(--font-latin), var(--font-cjk), sans-serif; white-space: nowrap; }
3111
3114
  .vditor-editor-host .vditor-content { position: relative; }
3112
- .vditor-editor-host .vditor-line-numbers { display: none; position: absolute; z-index: 1; inset: 0 auto 0 0; width: 42px; padding: 0; overflow: hidden; border-right: 1px solid var(--line); background: color-mix(in srgb, var(--surface-soft) 88%, transparent); color: var(--muted); font: 12px/1.75 var(--font-latin), monospace; text-align: right; user-select: none; pointer-events: none; will-change: transform; }
3115
+ .vditor-editor-host .vditor-line-numbers { display: none; position: absolute; z-index: 1; inset: 0 auto 0 0; width: 42px; padding: 0; overflow: hidden; border-right: 1px solid var(--line); background: color-mix(in srgb, var(--surface-soft) 88%, transparent); color: var(--muted); font: 12px/1.75 var(--font-latin), monospace; text-align: center; user-select: none; pointer-events: none; will-change: transform; }
3113
3116
  .vditor-editor-host.vditor.show-line-numbers .vditor-line-numbers { display: block; }
3114
- .vditor-editor-host .vditor-line-number { position: absolute; top: 0; right: 8px; left: 0; display: block; box-sizing: border-box; overflow: hidden; padding: 0; text-align: right; white-space: nowrap; }
3115
- .vditor-editor-host.vditor.show-line-numbers .vditor-ir, .vditor-editor-host.vditor.show-line-numbers .vditor-wysiwyg, .vditor-editor-host.vditor.show-line-numbers .vditor-sv, .vditor-editor-host.vditor.show-line-numbers .vditor-sv textarea { padding-left: 42px; }
3117
+ .vditor-editor-host .vditor-line-number { position: absolute; top: 0; right: 0; left: 0; display: block; box-sizing: border-box; overflow: hidden; padding: 0; text-align: center; white-space: nowrap; }
3118
+ .vditor-editor-host.vditor.show-line-numbers .vditor-sv, .vditor-editor-host.vditor.show-line-numbers .vditor-sv textarea { padding-left: 42px; }
3116
3119
  .vditor-editor-host .vditor-line-number-button[aria-pressed="true"] { color: var(--accent-dark); background: color-mix(in srgb, var(--accent) 16%, transparent); }
3117
3120
  .vditor-editor-host .vditor-content { min-height: 0; }
3118
3121
  .vditor-editor-host .vditor-reset { color: var(--ink); font-family: var(--font-cjk), var(--font-latin), sans-serif; }
@@ -3228,7 +3231,8 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
3228
3231
  .character-section-editor-title-input::placeholder { color: var(--ink); opacity: .92; }
3229
3232
  .character-section-editor-title-input:focus { border-color: var(--accent); box-shadow: none; }
3230
3233
  .character-markdown-editor { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: 12px; min-height: 0; padding: 16px 22px 18px; overflow: hidden; background: var(--surface-soft); }
3231
- .character-markdown-editor > .vditor-editor-host { width: 100%; max-width: 960px; justify-self: center; }
3234
+ .knowledge-markdown-editor { grid-template-rows: minmax(0, 1fr) auto; }
3235
+ .character-markdown-editor > .vditor-editor-host { width: 100%; justify-self: stretch; }
3232
3236
  .character-markdown-editor > .vditor-editor-host.vditor { border-color: color-mix(in srgb, var(--accent) 22%, var(--line)); box-shadow: 0 12px 34px color-mix(in srgb, var(--ink) 12%, transparent); transition: border-color .16s ease, box-shadow .16s ease; }
3233
3237
  .character-markdown-editor > .vditor-editor-host.vditor:focus-within { border-color: color-mix(in srgb, var(--accent) 62%, var(--line)); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 15%, transparent), 0 16px 42px color-mix(in srgb, var(--ink) 16%, transparent); }
3234
3238
  .character-markdown-editor-meta { display: grid; grid-template-columns: minmax(160px, .55fr) minmax(280px, 1.45fr); gap: 12px; }
@@ -3393,7 +3397,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
3393
3397
  .setting-markdown-field { height: 70dvh; }
3394
3398
  .setting-markdown-heading, .markdown-editor-field-heading { align-items: flex-start; flex-direction: column; gap: 4px; }
3395
3399
  .setting-markdown-field > .vditor-editor-host, .markdown-editor-field .vditor-editor-host { min-height: 42dvh; }
3396
- .editor-dialog .dialog-fields { grid-template-columns: minmax(0, 1fr); max-height: 76dvh; }
3400
+ .editor-dialog .dialog-fields { grid-template-columns: minmax(0, 1fr); max-height: min(76dvh, calc(100dvh - 264px)); }
3397
3401
  .editor-dialog .markdown-editor-field .vditor-editor-host.vditor { min-height: 52dvh !important; }
3398
3402
  .character-editor-workspace, .character-editor-workspace.history-open { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
3399
3403
  .character-editor-nav { flex-direction: row; overflow-x: auto; padding: 8px 10px; border-right: 0; border-bottom: 1px solid var(--line); }
@@ -3630,6 +3634,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
3630
3634
  }
3631
3635
  .dialog-header { padding: 14px 16px 12px; }
3632
3636
  .dialog-header h2 { font-size: 20px; }
3637
+ .dialog-title-input { width: min(100%, calc(100vw - 100px)); font-size: 20px; }
3633
3638
  .settings-dialog-header-actions { gap: 6px; }
3634
3639
  .dialog-fields, .appearance-grid, .access-dialog-body, .account-settings-body, .versions-list, .entity-history-list, .chapter-annotations-list { padding-inline: 16px; }
3635
3640
  .chapter-version-compare { grid-template-columns: minmax(0, 1fr); padding-inline: 16px; }
package/dist/store.js CHANGED
@@ -5284,6 +5284,19 @@ export class Store {
5284
5284
  }))
5285
5285
  };
5286
5286
  }
5287
+ getAiConversationLockedModelId(conversationId, workId) {
5288
+ const conversation = this.db.get("SELECT work_id FROM ai_conversations WHERE id = ?", conversationId);
5289
+ if (!conversation)
5290
+ throw notFound("AI 对话");
5291
+ if (requiredString(conversation, "work_id") !== workId)
5292
+ throw new AppError(400, "CONVERSATION_WORK_MISMATCH", "AI 对话不属于当前作品");
5293
+ const message = this.db.get(`SELECT metadata_json FROM ai_conversation_messages
5294
+ WHERE conversation_id = ? AND role = 'user'
5295
+ ORDER BY created_at, rowid
5296
+ LIMIT 1`, conversationId);
5297
+ const metadata = message ? json(requiredString(message, "metadata_json"), {}) : {};
5298
+ return typeof metadata.modelId === "string" && metadata.modelId.trim() ? metadata.modelId.trim() : null;
5299
+ }
5287
5300
  getAiConversationInjectedEntities(conversationId, workId) {
5288
5301
  const conversation = this.db.get("SELECT work_id, injected_entities_json FROM ai_conversations WHERE id = ?", conversationId);
5289
5302
  if (!conversation)
@@ -5705,6 +5718,16 @@ export class Store {
5705
5718
  }
5706
5719
  mapAiConversation(row) {
5707
5720
  const roleplayCharacterId = optionalString(row, "roleplay_character_id");
5721
+ const firstUserMessage = this.db.get(`SELECT metadata_json FROM ai_conversation_messages
5722
+ WHERE conversation_id = ? AND role = 'user'
5723
+ ORDER BY created_at, rowid
5724
+ LIMIT 1`, requiredString(row, "id"));
5725
+ const firstUserMetadata = firstUserMessage
5726
+ ? json(requiredString(firstUserMessage, "metadata_json"), {})
5727
+ : {};
5728
+ const lockedModelId = typeof firstUserMetadata.modelId === "string" && firstUserMetadata.modelId.trim()
5729
+ ? firstUserMetadata.modelId.trim()
5730
+ : null;
5708
5731
  const roleplayCharacter = roleplayCharacterId
5709
5732
  ? this.db.get("SELECT id, name, code FROM characters WHERE id = ? AND work_id = ?", roleplayCharacterId, requiredString(row, "work_id"))
5710
5733
  : undefined;
@@ -5718,6 +5741,7 @@ export class Store {
5718
5741
  hasCompactedSummary: Boolean(requiredString(row, "compacted_summary")),
5719
5742
  contextWarningPending: Boolean(optionalString(row, "context_warning_at")),
5720
5743
  taskType: optionalString(row, "task_type") ?? (roleplayCharacterId ? "roleplay" : "chat"),
5744
+ ...(lockedModelId ? { modelId: lockedModelId } : {}),
5721
5745
  contextScope: json(optionalString(row, "context_scope_json") ?? "", { type: "none" }),
5722
5746
  roleplayCharacter: roleplayCharacter ? {
5723
5747
  id: requiredString(roleplayCharacter, "id"),