feat: 更新插件至 v0.4.6

- 更新核心功能代码
- 优化样式和 UI
- 更新提示词配置
- 更新流程配置

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
user
2026-01-26 00:58:57 +08:00
parent f51c4ef6dc
commit 84dc04ef61
11 changed files with 1123 additions and 18701 deletions

Binary file not shown.

18688
index.js

File diff suppressed because one or more lines are too long

View File

@@ -1,13 +1,15 @@
{ {
"display_name": "记忆管理并发系统", "display_name": "记忆管理并发系统",
"loading_order": 100, "description": "智能记忆检索与注入系统,支持并发处理、世界书管理和剧情优化",
"requires": [], "version": "0.4.6",
"optional": [], "author": "可乐、繁华",
"homePage": "https://github.com/Cola-Echo/memory-manager-concurrent",
"js": "index.js", "js": "index.js",
"css": "style.css", "css": "style.css",
"author": "可乐、繁华", "loading_order": 100,
"version": "0.3.0",
"homePage": "",
"auto_update": false, "auto_update": false,
"requires": [],
"optional": [],
"minimum_client_version": "1.12.0",
"generate_interceptor": "MemoryManagerConcurrent_intercept" "generate_interceptor": "MemoryManagerConcurrent_intercept"
} }

892
style.css
View File

@@ -1218,6 +1218,12 @@
overflow: hidden; overflow: hidden;
} }
.mm-settings-header-actions {
display: flex;
align-items: center;
gap: 8px;
}
.mm-settings-header h3 { .mm-settings-header h3 {
margin: 0; margin: 0;
font-size: 16px; font-size: 16px;
@@ -3096,7 +3102,7 @@
.mm-msg-progress-bar-fill { .mm-msg-progress-bar-fill {
height: 100%; height: 100%;
border-radius: 4px; border-radius: 4px;
transition: width 0.5s ease-out; transition: none; /* 禁用 CSS transition由 JS 动画控制 */
position: relative; position: relative;
} }
@@ -4914,8 +4920,72 @@
/* 世界书列表容器 */ /* 世界书列表容器 */
.mm-config-worldbook-content { .mm-config-worldbook-content {
max-height: 200px; max-height: 250px;
overflow-y: auto; overflow-y: auto;
display: flex;
flex-direction: column;
}
/* 世界书搜索框 */
.mm-config-worldbook-search {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 10px;
background: var(--mm-bg-secondary);
border-radius: calc(var(--mm-radius) - 2px);
margin-bottom: 8px;
position: sticky;
top: 0;
z-index: 1;
}
.mm-config-worldbook-search i.fa-search {
color: var(--mm-text-muted);
font-size: 0.85em;
}
.mm-config-worldbook-search input {
flex: 1;
background: none;
border: none;
color: var(--mm-text);
font-size: 0.9em;
padding: 4px 6px;
outline: none;
}
.mm-config-worldbook-search input::placeholder {
color: var(--mm-text-muted);
}
/* 世界书拖拽调整高度手柄 */
.mm-config-worldbook-resize-handle {
display: flex;
align-items: center;
justify-content: center;
height: 16px;
cursor: ns-resize;
color: var(--mm-text-muted);
font-size: 0.75em;
opacity: 0.6;
transition: var(--mm-transition);
user-select: none;
-webkit-user-select: none;
touch-action: none;
}
.mm-config-worldbook-resize-handle:hover,
.mm-config-worldbook-resize-handle:active {
opacity: 1;
color: var(--mm-primary);
background: rgba(var(--mm-primary-rgb, 74, 144, 217), 0.1);
}
.mm-config-worldbook-resize-handle.dragging {
opacity: 1;
color: var(--mm-primary);
background: rgba(var(--mm-primary-rgb, 74, 144, 217), 0.15);
} }
.mm-config-worldbook-list { .mm-config-worldbook-list {
@@ -4966,6 +5036,36 @@
color: var(--mm-text-muted); color: var(--mm-text-muted);
} }
/* 世界书全选/全不选按钮 */
.mm-config-worldbook-actions {
display: flex;
align-items: center;
gap: 4px;
margin-left: auto;
}
.mm-config-worldbook-actions .mm-btn-icon-small {
width: 24px;
height: 24px;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
background: transparent;
border: 1px solid var(--mm-border);
border-radius: 4px;
color: var(--mm-text-muted);
cursor: pointer;
transition: var(--mm-transition);
font-size: 0.8em;
}
.mm-config-worldbook-actions .mm-btn-icon-small:hover {
background: var(--mm-bg-tertiary);
color: var(--mm-text);
border-color: var(--mm-primary);
}
/* 世界书条目列表 */ /* 世界书条目列表 */
.mm-config-worldbook-entries { .mm-config-worldbook-entries {
display: none; display: none;
@@ -5775,6 +5875,12 @@
font-size: 0.9em; font-size: 0.9em;
} }
/* 关闭按钮靠左 */
.mm-plot-actions .mm-btn-close {
margin-right: auto;
padding: 8px 12px;
}
.mm-btn-success { .mm-btn-success {
background: var(--mm-success); background: var(--mm-success);
color: white; color: white;
@@ -6773,3 +6879,785 @@
.mm-prompt-part-block[data-source="jailbreak"] { .mm-prompt-part-block[data-source="jailbreak"] {
display: none !important; display: none !important;
} }
/* ============================================================================
多AI生成功能样式
============================================================================ */
/* 多AI provider列表 */
.mm-multi-ai-provider-section {
margin-top: 12px;
}
.mm-multi-ai-section-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
}
.mm-multi-ai-section-title {
font-size: 12px;
font-weight: 500;
color: var(--mm-text-muted);
}
.mm-multi-ai-provider-list {
display: flex;
flex-direction: column;
gap: 6px;
max-height: 200px;
overflow-y: auto;
}
.mm-multi-ai-provider-item {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
padding: 10px 12px;
background: var(--mm-bg-secondary);
border: 1px solid var(--mm-border);
border-radius: calc(var(--mm-radius) - 2px);
transition: all 0.2s ease;
}
.mm-multi-ai-provider-item:hover {
border-color: var(--mm-primary);
}
.mm-multi-ai-provider-info {
display: flex;
flex-direction: column;
gap: 4px;
flex: 1;
min-width: 0;
}
.mm-multi-ai-provider-checkbox {
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
}
.mm-multi-ai-provider-checkbox input[type="checkbox"] {
width: 14px;
height: 14px;
accent-color: var(--mm-primary);
cursor: pointer;
}
.mm-multi-ai-provider-name {
font-size: 13px;
font-weight: 500;
color: var(--mm-text);
}
.mm-multi-ai-provider-details {
font-size: 11px;
color: var(--mm-text-muted);
margin-left: 22px;
}
.mm-multi-ai-provider-actions {
display: flex;
gap: 4px;
flex-shrink: 0;
}
.mm-multi-ai-provider-empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
padding: 24px;
color: var(--mm-text-muted);
font-size: 13px;
}
.mm-multi-ai-provider-empty i {
font-size: 24px;
opacity: 0.5;
}
.mm-multi-ai-actions {
display: flex;
gap: 8px;
margin-top: 10px;
}
.mm-multi-ai-hint {
margin-top: 12px;
display: block;
}
/* 多AI配置弹窗 */
#mm-multi-ai-config-modal {
background: transparent;
pointer-events: none;
}
#mm-multi-ai-config-modal .mm-modal-content {
max-width: 500px;
pointer-events: auto;
}
#mm-multi-ai-config-modal .mm-model-input-row {
display: flex;
gap: 8px;
}
#mm-multi-ai-config-modal .mm-model-select {
flex: 1;
}
#mm-multi-ai-config-modal .mm-form-row {
display: flex;
gap: 16px;
}
#mm-multi-ai-config-modal .mm-form-row .mm-form-group {
flex: 1;
}
#mm-multi-ai-config-modal .mm-test-result {
margin-left: 10px;
font-size: 12px;
}
#mm-multi-ai-config-modal .mm-test-result.mm-test-success {
color: var(--mm-success);
}
#mm-multi-ai-config-modal .mm-test-result.mm-test-error {
color: var(--mm-danger);
}
/* 多AI选择弹窗 */
.mm-multi-ai-modal-content {
max-width: 95vw;
width: auto;
min-width: 400px;
}
.mm-multi-ai-cards {
display: flex;
gap: 15px;
overflow-x: auto;
padding: 10px 0;
max-width: 100%;
}
.mm-multi-ai-cards.mm-mobile {
flex-direction: column;
overflow-x: visible;
}
.mm-multi-ai-card {
display: flex;
flex-direction: column;
min-width: 350px;
max-width: 450px;
flex-shrink: 0;
background: var(--mm-bg-card);
border: 1px solid var(--mm-border);
border-radius: var(--mm-radius);
overflow: hidden;
transition: all 0.2s ease;
}
.mm-multi-ai-card:hover {
border-color: var(--mm-primary);
}
.mm-multi-ai-card.complete {
border-color: var(--mm-success);
}
.mm-multi-ai-card.error {
border-color: var(--mm-danger);
}
.mm-multi-ai-card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
background: var(--mm-bg-secondary);
border-bottom: 1px solid var(--mm-border);
}
.mm-multi-ai-info {
display: flex;
flex-direction: column;
gap: 2px;
}
.mm-multi-ai-name {
font-size: 14px;
font-weight: 600;
color: var(--mm-text);
}
.mm-multi-ai-model {
font-size: 11px;
color: var(--mm-text-muted);
}
.mm-multi-ai-stats {
display: flex;
align-items: center;
gap: 8px;
}
.mm-multi-ai-tokens {
font-size: 12px;
color: var(--mm-success, #6bcb77);
font-weight: 600;
font-variant-numeric: tabular-nums;
padding: 2px 6px;
background: rgba(107, 203, 119, 0.15);
border-radius: 4px;
}
.mm-multi-ai-timer {
font-size: 12px;
color: var(--mm-primary);
font-weight: 600;
font-variant-numeric: tabular-nums;
}
.mm-multi-ai-content {
flex: 1;
min-height: 200px;
max-height: 400px;
overflow-y: auto;
padding: 16px;
background: var(--mm-bg);
}
.mm-multi-ai-content.mm-streaming .mm-multi-ai-text::after {
content: '█';
animation: mm-blink 1s step-end infinite;
color: var(--mm-primary);
}
@keyframes mm-blink {
0%, 50% { opacity: 1; }
51%, 100% { opacity: 0; }
}
.mm-multi-ai-text {
font-size: 13px;
line-height: 1.6;
color: var(--mm-text);
white-space: pre-wrap;
word-break: break-word;
}
.mm-multi-ai-loader {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 12px;
height: 100%;
color: var(--mm-text-muted);
font-size: 13px;
}
.mm-loader-spinner {
width: 36px;
height: 36px;
border: 3px solid var(--mm-border);
border-top-color: var(--mm-primary);
border-radius: 50%;
animation: mm-spin 1s linear infinite;
}
@keyframes mm-spin {
to { transform: rotate(360deg); }
}
.mm-multi-ai-error {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
height: 100%;
color: var(--mm-danger);
text-align: center;
}
.mm-multi-ai-error i {
font-size: 32px;
}
.mm-multi-ai-error small {
font-size: 11px;
color: var(--mm-text-muted);
max-width: 80%;
word-break: break-word;
}
.mm-multi-ai-card-footer {
display: flex;
gap: 8px;
padding: 12px 16px;
background: var(--mm-bg-secondary);
border-top: 1px solid var(--mm-border);
}
.mm-multi-ai-card-footer .mm-btn {
flex: 1;
}
.mm-multi-ai-scroll-hint {
text-align: center;
font-size: 11px;
color: var(--mm-text-muted);
padding: 8px 0;
}
/* 移动端标签页 */
.mm-multi-ai-tabs {
display: none;
gap: 4px;
margin-bottom: 10px;
overflow-x: auto;
padding-bottom: 8px;
}
.mm-multi-ai-cards.mm-mobile + .mm-multi-ai-scroll-hint {
display: none;
}
@media (max-width: 768px) {
.mm-multi-ai-modal-content {
width: calc(100vw - 24px);
min-width: auto;
}
.mm-multi-ai-tabs {
display: flex;
}
.mm-multi-ai-tab {
padding: 8px 16px;
background: var(--mm-bg-secondary);
border: 1px solid var(--mm-border);
border-radius: 16px;
color: var(--mm-text-muted);
font-size: 12px;
cursor: pointer;
white-space: nowrap;
transition: all 0.2s ease;
}
.mm-multi-ai-tab.active {
background: var(--mm-primary);
border-color: var(--mm-primary);
color: white;
}
.mm-multi-ai-card {
min-width: auto;
max-width: none;
}
.mm-multi-ai-content {
min-height: 250px;
max-height: 50vh;
}
}
/* 极小按钮 */
.mm-btn-xs {
padding: 4px 8px !important;
font-size: 11px !important;
min-width: auto;
}
/* 危险按钮 */
.mm-btn-danger {
background: transparent;
border: 1px solid var(--mm-danger);
color: var(--mm-danger);
}
.mm-btn-danger:hover {
background: var(--mm-danger);
color: white;
}
/* ==================== 提示词预设相关样式 ==================== */
/* 预设选择区域 */
.mm-preset-select-group {
margin-top: 16px;
padding-top: 16px;
border-top: 1px dashed var(--mm-border);
}
.mm-preset-checkbox-label {
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
font-weight: 500;
}
.mm-preset-checkbox-label input[type="checkbox"] {
width: 16px;
height: 16px;
cursor: pointer;
}
.mm-preset-options {
margin-top: 12px;
padding: 12px;
background: var(--mm-bg-secondary);
border-radius: var(--mm-radius);
}
.mm-preset-select-row {
display: flex;
gap: 8px;
align-items: center;
}
.mm-preset-select-row select {
flex: 1;
}
.mm-preset-preview {
margin-top: 10px;
}
.mm-preset-preview-info {
display: flex;
flex-direction: column;
gap: 4px;
}
.mm-preset-preview-count {
font-size: 12px;
color: var(--mm-text-muted);
}
.mm-preset-preview-names {
font-size: 11px;
color: var(--mm-text-muted);
opacity: 0.7;
}
.mm-preset-preview-empty {
font-size: 12px;
color: var(--mm-danger);
}
/* 提示词预设列表(设置界面) */
.mm-prompt-preset-section {
margin-top: 12px;
}
.mm-prompt-preset-list {
display: flex;
flex-direction: column;
gap: 8px;
}
.mm-prompt-preset-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 12px;
background: var(--mm-bg-secondary);
border: 1px solid var(--mm-border);
border-radius: var(--mm-radius);
transition: all 0.2s ease;
}
.mm-prompt-preset-item:hover {
border-color: var(--mm-primary-light);
}
.mm-preset-info {
display: flex;
align-items: center;
gap: 8px;
}
.mm-preset-name {
font-weight: 500;
}
.mm-preset-count {
font-size: 12px;
color: var(--mm-text-muted);
}
.mm-preset-actions {
display: flex;
gap: 4px;
}
.mm-prompt-preset-empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
padding: 20px;
color: var(--mm-text-muted);
font-size: 13px;
}
.mm-prompt-preset-empty i {
font-size: 24px;
opacity: 0.5;
}
/* 提示词预设配置弹窗 */
#mm-prompt-preset-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: transparent;
display: none;
align-items: center;
justify-content: center;
z-index: 9999;
pointer-events: none;
}
#mm-prompt-preset-modal.mm-modal-visible {
display: flex;
}
#mm-prompt-preset-modal .mm-modal-content {
pointer-events: auto;
}
.mm-prompt-preset-modal-content {
max-width: 700px;
max-height: 85vh;
}
.mm-preset-import-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.mm-prompt-list-container {
max-height: 400px;
overflow-y: auto;
border: 1px solid var(--mm-border);
border-radius: var(--mm-radius);
background: var(--mm-bg-secondary);
}
.mm-prompt-list-actions {
margin-top: 10px;
}
/* 提示词项 */
.mm-prompt-item {
border-bottom: 1px solid var(--mm-border);
transition: all 0.2s ease;
}
.mm-prompt-item:last-child {
border-bottom: none;
}
.mm-prompt-item.mm-prompt-disabled {
opacity: 0.5;
}
.mm-prompt-item.mm-dragging {
opacity: 0.5;
background: var(--mm-primary-light);
}
.mm-prompt-item.mm-drag-over-top {
border-top: 2px solid var(--mm-primary);
}
.mm-prompt-item.mm-drag-over-bottom {
border-bottom: 2px solid var(--mm-primary);
}
.mm-prompt-item-header {
display: flex;
align-items: center;
gap: 8px;
padding: 10px 12px;
cursor: move;
}
.mm-prompt-drag-handle {
color: var(--mm-text-muted);
cursor: grab;
}
.mm-prompt-drag-handle:active {
cursor: grabbing;
}
.mm-prompt-enable-label {
display: flex;
align-items: center;
}
.mm-prompt-enable-label input[type="checkbox"] {
width: 14px;
height: 14px;
}
.mm-prompt-name {
font-weight: 500;
flex: 1;
}
.mm-prompt-type-badge {
padding: 2px 8px;
border-radius: 10px;
font-size: 10px;
font-weight: 500;
text-transform: uppercase;
}
.mm-prompt-type-custom {
background: var(--mm-primary-light);
color: var(--mm-primary);
}
.mm-prompt-type-memory {
background: rgba(var(--mm-success-rgb, 46, 204, 113), 0.15);
color: var(--mm-success);
}
.mm-prompt-type-history,
.mm-prompt-type-character {
background: rgba(var(--mm-warning-rgb, 241, 196, 15), 0.15);
color: var(--mm-warning, #f1c40f);
}
.mm-prompt-type-user {
background: rgba(var(--mm-info-rgb, 52, 152, 219), 0.15);
color: var(--mm-info, #3498db);
}
.mm-prompt-history-count {
font-size: 12px;
color: var(--mm-text-muted);
display: flex;
align-items: center;
gap: 4px;
}
.mm-prompt-history-input {
width: 50px;
padding: 2px 4px;
text-align: center;
}
.mm-prompt-item-actions {
display: flex;
gap: 4px;
margin-left: auto;
}
.mm-prompt-item-content {
padding: 0 12px 12px 12px;
}
.mm-prompt-content-editor {
width: 100%;
min-height: 80px;
padding: 8px;
font-family: monospace;
font-size: 12px;
border: 1px solid var(--mm-border);
border-radius: var(--mm-radius-sm) var(--mm-radius-sm) 0 0;
background: var(--mm-bg-primary);
color: var(--mm-text-primary);
resize: none;
}
.mm-prompt-content-preview {
padding: 10px;
background: var(--mm-bg-primary);
border-radius: var(--mm-radius-sm) var(--mm-radius-sm) 0 0;
font-size: 12px;
color: var(--mm-text-muted);
min-height: 80px;
max-height: 300px;
overflow-y: auto;
}
/* 可调整大小的容器 */
.mm-prompt-resizable-container {
position: relative;
}
.mm-prompt-resizable-container .mm-resize-handle {
border-radius: 0 0 var(--mm-radius-sm) var(--mm-radius-sm);
}
/* 类型说明 */
.mm-prompt-type-desc {
font-style: italic;
margin-bottom: 8px;
}
/* 实时预览内容 */
.mm-prompt-preview-content {
background: var(--mm-bg-secondary);
border-radius: var(--mm-radius-sm);
padding: 8px;
margin-top: 8px;
}
.mm-prompt-preview-content pre {
margin: 0;
white-space: pre-wrap;
word-break: break-word;
font-family: monospace;
font-size: 11px;
color: var(--mm-text-primary);
}
/* 空内容提示 */
.mm-prompt-preview-empty {
color: var(--mm-text-muted);
font-size: 11px;
opacity: 0.7;
}
/* 字符统计 */
.mm-prompt-char-count {
font-size: 11px;
color: var(--mm-text-muted);
background: var(--mm-bg-secondary);
padding: 2px 6px;
border-radius: 10px;
margin-left: 4px;
}
/* ST类型标签样式 */
.mm-prompt-type-charDescription,
.mm-prompt-type-personaDescription,
.mm-prompt-type-worldInfoBefore,
.mm-prompt-type-worldInfoAfter,
.mm-prompt-type-dialogueExamples {
background: linear-gradient(135deg, #5a8a7a, #4a7a6a);
}

View File

@@ -89,7 +89,7 @@
</div> </div>
</div> </div>
<div class="mm-author-section"> <div class="mm-author-section">
<div class="mm-author-info"><span class="mm-author-text">By可乐、繁华 | v0.3.0</span> <button class="mm-paw-btn" id="mm-paw-btn" title="点我~">🐾</button></div> <div class="mm-author-info"><span class="mm-author-text">By可乐、繁华 | v0.4.1</span> <button class="mm-paw-btn" id="mm-paw-btn" title="点我~">🐾</button></div>
<div class="mm-flower-container" id="mm-flower-container"></div> <div class="mm-flower-container" id="mm-flower-container"></div>
</div> </div>
<div class="mm-theme-switcher"> <div class="mm-theme-switcher">

View File

@@ -56,6 +56,9 @@
<!-- 操作按钮 --> <!-- 操作按钮 -->
<div class="mm-plot-actions"> <div class="mm-plot-actions">
<button id="mm-plot-close-btn" class="mm-btn mm-btn-secondary mm-btn-close" title="关闭面板">
<i class="fa-solid fa-xmark"></i>
</button>
<button id="mm-plot-accept-btn" class="mm-btn mm-btn-success" disabled> <button id="mm-plot-accept-btn" class="mm-btn mm-btn-success" disabled>
<i class="fa-solid fa-check"></i> 接受 <i class="fa-solid fa-check"></i> 接受
</button> </button>

View File

@@ -1,4 +1,4 @@
<!-- 交互式记忆搜索对话面板 --> <!-- 记忆搜索助手对话面板 -->
<div id="mm-search-dialog" class="mm-search-panel"> <div id="mm-search-dialog" class="mm-search-panel">
<div class="mm-search-panel-header" id="mm-search-header-toggle" style="cursor: pointer;"> <div class="mm-search-panel-header" id="mm-search-header-toggle" style="cursor: pointer;">
<span class="mm-search-panel-title"> <span class="mm-search-panel-title">

View File

@@ -2,9 +2,14 @@
<div id="memory-manager-settings" class="mm-settings"> <div id="memory-manager-settings" class="mm-settings">
<div class="mm-settings-header"> <div class="mm-settings-header">
<h3>设置</h3> <h3>设置</h3>
<button id="mm-settings-close" class="mm-btn mm-btn-icon"> <div class="mm-settings-header-actions">
<i class="fa-solid fa-times"></i> <button id="mm-clear-old-data" class="mm-btn mm-btn-secondary mm-btn-xs" title="清除旧数据1分钟前就算旧数据">
</button> <i class="fa-solid fa-broom"></i> 清除旧数据
</button>
<button id="mm-settings-close" class="mm-btn mm-btn-icon" title="关闭">
<i class="fa-solid fa-times"></i>
</button>
</div>
</div> </div>
<div class="mm-settings-content"> <div class="mm-settings-content">
@@ -404,6 +409,69 @@
</div> </div>
</div> </div>
</div> </div>
<!-- 多AI生成可折叠 -->
<div class="mm-collapse-card" id="mm-multi-ai-card">
<div class="mm-collapse-header" id="mm-multi-ai-toggle">
<div class="mm-collapse-title">
<i class="fa-solid fa-robot"></i>
<span>多AI生成</span>
<span class="mm-collapse-badge" id="mm-multi-ai-badge">关闭</span>
</div>
<i class="fa-solid fa-chevron-down mm-collapse-arrow"></i>
</div>
<div class="mm-collapse-body">
<!-- 启用开关 -->
<div class="mm-setting-item">
<label>
<input type="checkbox" id="mm-enable-multi-ai" />
启用多AI生成功能
</label>
<small class="mm-hint">启用后在汇总检查弹窗中显示「多AI生成」按钮</small>
</div>
<!-- 已配置的API列表 -->
<div class="mm-multi-ai-provider-section">
<div class="mm-multi-ai-section-header">
<span class="mm-multi-ai-section-title">已配置的API列表</span>
</div>
<div class="mm-multi-ai-provider-list" id="mm-multi-ai-provider-list">
<!-- 动态生成provider列表项 -->
</div>
<div class="mm-multi-ai-provider-empty" id="mm-multi-ai-provider-empty">
<i class="fa-solid fa-plug"></i>
<span>暂无API配置</span>
</div>
<div class="mm-multi-ai-actions">
<button type="button" id="mm-multi-ai-add" class="mm-btn mm-btn-secondary">
<i class="fa-solid fa-plus"></i> 添加API配置
</button>
<button type="button" id="mm-multi-ai-add-preset" class="mm-btn mm-btn-secondary">
<i class="fa-solid fa-file-lines"></i> 添加提示词预设
</button>
</div>
</div>
<!-- 已保存的提示词预设 -->
<div class="mm-multi-ai-provider-section mm-prompt-preset-section">
<div class="mm-multi-ai-section-header">
<span class="mm-multi-ai-section-title">已保存的提示词预设</span>
</div>
<div class="mm-prompt-preset-list" id="mm-prompt-preset-list">
<!-- 动态生成预设列表项 -->
</div>
<div class="mm-prompt-preset-empty" id="mm-prompt-preset-empty">
<i class="fa-solid fa-file-lines"></i>
<span>暂无提示词预设</span>
</div>
</div>
<small class="mm-hint mm-multi-ai-hint">
<i class="fa-solid fa-info-circle"></i>
至少需要配置2个已启用的API才能使用多AI生成功能
</small>
</div>
</div>
</div> </div>
</div> </div>
@@ -804,17 +872,32 @@
<i class="fa-solid fa-chevron-down mm-collapse-arrow"></i> <i class="fa-solid fa-chevron-down mm-collapse-arrow"></i>
</div> </div>
<div class="mm-collapse-body"> <div class="mm-collapse-body">
<div class="mm-config-worldbook-content"> <div class="mm-config-worldbook-content" id="mm-config-worldbook-content">
<!-- 搜索框 -->
<div class="mm-config-worldbook-search">
<i class="fa-solid fa-search"></i>
<input type="text" id="mm-config-worldbook-search-input" placeholder="搜索世界书或条目..." />
<button type="button" id="mm-config-worldbook-search-clear" class="mm-btn-icon-small" title="清除" style="display: none;">
<i class="fa-solid fa-times"></i>
</button>
</div>
<div id="mm-config-worldbook-loading" class="mm-loading-state" style="display: none;"> <div id="mm-config-worldbook-loading" class="mm-loading-state" style="display: none;">
<i class="fa-solid fa-spinner fa-spin"></i><span>加载中...</span> <i class="fa-solid fa-spinner fa-spin"></i><span>加载中...</span>
</div> </div>
<div id="mm-config-worldbook-empty" class="mm-empty-state" style="display: none;"> <div id="mm-config-worldbook-empty" class="mm-empty-state" style="display: none;">
<i class="fa-solid fa-book-open"></i><span>未找到世界书</span> <i class="fa-solid fa-book-open"></i><span>未找到世界书</span>
</div> </div>
<div id="mm-config-worldbook-no-results" class="mm-empty-state" style="display: none;">
<i class="fa-solid fa-search"></i><span>无匹配结果</span>
</div>
<div class="mm-config-worldbook-list" id="mm-config-worldbook-list"> <div class="mm-config-worldbook-list" id="mm-config-worldbook-list">
<!-- 动态生成世界书列表 --> <!-- 动态生成世界书列表 -->
</div> </div>
</div> </div>
<!-- 拖拽调整高度手柄 -->
<div class="mm-config-worldbook-resize-handle" id="mm-config-worldbook-resize-handle" title="拖拽调整高度">
<i class="fa-solid fa-grip-lines"></i>
</div>
</div> </div>
</div> </div>
@@ -905,3 +988,135 @@
</div> </div>
</div> </div>
</div> </div>
<!-- 多AI配置弹窗 -->
<div id="mm-multi-ai-config-modal" class="mm-modal">
<div class="mm-modal-content">
<div class="mm-modal-header">
<h4 id="mm-multi-ai-config-title">配置AI: 新建配置</h4>
<button class="mm-modal-close mm-btn mm-btn-icon">
<i class="fa-solid fa-times"></i>
</button>
</div>
<div class="mm-modal-body">
<!-- 配置名称 -->
<div class="mm-form-group">
<label>配置名称 <span class="mm-required">*</span></label>
<input type="text" id="mm-multi-ai-name" placeholder="例如: GPT-4" />
<small class="mm-hint">用于在选择弹窗中显示</small>
</div>
<!-- API 格式 -->
<div class="mm-form-group">
<label>API 格式</label>
<div class="mm-radio-group">
<label><input type="radio" name="mm-multi-ai-format" value="openai" checked /> OpenAI 兼容</label>
<label><input type="radio" name="mm-multi-ai-format" value="anthropic" /> Anthropic</label>
<label><input type="radio" name="mm-multi-ai-format" value="google" /> Google</label>
<label><input type="radio" name="mm-multi-ai-format" value="custom" /> 自定义</label>
</div>
</div>
<!-- API URL -->
<div class="mm-form-group">
<label>API URL <span class="mm-required">*</span></label>
<input type="text" id="mm-multi-ai-url" placeholder="https://api.openai.com/v1" />
<small class="mm-hint">填写到 /v1 即可,会自动补全完整路径</small>
</div>
<!-- API Key -->
<div class="mm-form-group">
<label>API Key</label>
<input type="password" id="mm-multi-ai-key" placeholder="sk-..." />
<small class="mm-hint">本地模型可留空</small>
</div>
<!-- 模型名称 -->
<div class="mm-form-group">
<label>模型名称 <span class="mm-required">*</span></label>
<div class="mm-model-input-row">
<select id="mm-multi-ai-model" class="mm-model-select">
<option value="" disabled selected>--- 请获取模型 ---</option>
</select>
<button type="button" id="mm-multi-ai-fetch-models" class="mm-btn mm-btn-secondary" title="从API获取模型列表">
<i class="fa-solid fa-download"></i> 获取模型
</button>
</div>
</div>
<!-- Max Tokens 和 Temperature -->
<div class="mm-form-row">
<div class="mm-form-group">
<label>Max Tokens</label>
<input type="number" id="mm-multi-ai-max-tokens" value="4000" min="100" max="32000" />
</div>
<div class="mm-form-group">
<label>Temperature</label>
<input type="range" id="mm-multi-ai-temperature" value="0.7" min="0" max="1" step="0.1" />
<span id="mm-multi-ai-temperature-value">0.7</span>
</div>
</div>
<!-- 输出模式 -->
<div class="mm-form-group">
<label>输出模式</label>
<div class="mm-radio-group">
<label><input type="radio" name="mm-multi-ai-streaming" value="true" checked /> 流式输出(实时显示)</label>
<label><input type="radio" name="mm-multi-ai-streaming" value="false" /> 非流式(等待完成)</label>
</div>
</div>
<!-- 自定义格式专用 -->
<div id="mm-multi-ai-custom-options" class="mm-hidden">
<div class="mm-form-group">
<label>自定义请求模板 (JSON)</label>
<textarea id="mm-multi-ai-custom-template" rows="4" placeholder='{"model": "{{model}}", "prompt": "{{system}}\n\n{{user}}"}'></textarea>
<small class="mm-hint">可用变量: {{system}}, {{user}}, {{model}}, {{max_tokens}}, {{temperature}}</small>
</div>
<div class="mm-form-group">
<label>响应解析路径</label>
<input type="text" id="mm-multi-ai-response-path" placeholder="choices.0.message.content" />
</div>
</div>
<!-- 提示词预设选择 -->
<div class="mm-form-group mm-preset-select-group">
<label class="mm-preset-checkbox-label">
<input type="checkbox" id="mm-multi-ai-use-preset" />
<span>使用提示词预设</span>
</label>
<small class="mm-hint">启用后将使用预设构建消息(包含系统提示词、聊天历史等)</small>
<div id="mm-multi-ai-preset-options" class="mm-preset-options mm-hidden">
<div class="mm-preset-select-row">
<select id="mm-multi-ai-preset-select">
<option value="">-- 请选择预设 --</option>
</select>
<button type="button" id="mm-multi-ai-edit-preset" class="mm-btn mm-btn-icon" title="编辑预设">
<i class="fa-solid fa-pen"></i>
</button>
<button type="button" id="mm-multi-ai-new-preset" class="mm-btn mm-btn-icon" title="新建预设">
<i class="fa-solid fa-plus"></i>
</button>
</div>
<div id="mm-multi-ai-preset-preview" class="mm-preset-preview"></div>
</div>
</div>
<!-- 测试连接 -->
<div class="mm-form-group">
<button id="mm-multi-ai-test" class="mm-btn mm-btn-secondary">
<i class="fa-solid fa-link"></i> 测试连接
</button>
<span id="mm-multi-ai-test-result" class="mm-test-result"></span>
</div>
</div>
<div class="mm-modal-footer">
<button id="mm-multi-ai-cancel" class="mm-btn mm-btn-secondary">取消</button>
<button id="mm-multi-ai-save" class="mm-btn mm-btn-primary">保存配置</button>
</div>
</div>
</div>