@waifucave/discord-waifus 1.5.154
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/LICENSE +21 -0
- package/README.md +230 -0
- package/THIRD_PARTY_NOTICES.md +26 -0
- package/assets/ocr/eng.traineddata +0 -0
- package/bin/waifus.mjs +36 -0
- package/dist/api/errors.d.ts +9 -0
- package/dist/api/errors.js +23 -0
- package/dist/api/errors.js.map +1 -0
- package/dist/api/server.d.ts +19 -0
- package/dist/api/server.js +1290 -0
- package/dist/api/server.js.map +1 -0
- package/dist/backend/logger.d.ts +20 -0
- package/dist/backend/logger.js +65 -0
- package/dist/backend/logger.js.map +1 -0
- package/dist/backend/migrations.d.ts +4 -0
- package/dist/backend/migrations.js +521 -0
- package/dist/backend/migrations.js.map +1 -0
- package/dist/backend/redaction.d.ts +1 -0
- package/dist/backend/redaction.js +22 -0
- package/dist/backend/redaction.js.map +1 -0
- package/dist/backend/runtime.d.ts +30 -0
- package/dist/backend/runtime.js +49 -0
- package/dist/backend/runtime.js.map +1 -0
- package/dist/backend/server.d.ts +18 -0
- package/dist/backend/server.js +581 -0
- package/dist/backend/server.js.map +1 -0
- package/dist/cli/commands.d.ts +35 -0
- package/dist/cli/commands.js +510 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/main.d.ts +1 -0
- package/dist/cli/main.js +12 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/parser.d.ts +10 -0
- package/dist/cli/parser.js +64 -0
- package/dist/cli/parser.js.map +1 -0
- package/dist/config/appConfig.d.ts +3 -0
- package/dist/config/appConfig.js +27 -0
- package/dist/config/appConfig.js.map +1 -0
- package/dist/config/layout.d.ts +13 -0
- package/dist/config/layout.js +173 -0
- package/dist/config/layout.js.map +1 -0
- package/dist/config/paths.d.ts +5 -0
- package/dist/config/paths.js +20 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/prebuiltWaifus.d.ts +3 -0
- package/dist/config/prebuiltWaifus.js +106 -0
- package/dist/config/prebuiltWaifus.js.map +1 -0
- package/dist/discord/client.d.ts +394 -0
- package/dist/discord/client.js +1196 -0
- package/dist/discord/client.js.map +1 -0
- package/dist/discord/contextBuilder.d.ts +15 -0
- package/dist/discord/contextBuilder.js +18 -0
- package/dist/discord/contextBuilder.js.map +1 -0
- package/dist/discord/intents.d.ts +5 -0
- package/dist/discord/intents.js +21 -0
- package/dist/discord/intents.js.map +1 -0
- package/dist/discord/memberCache.d.ts +12 -0
- package/dist/discord/memberCache.js +55 -0
- package/dist/discord/memberCache.js.map +1 -0
- package/dist/discord/normalization.d.ts +34 -0
- package/dist/discord/normalization.js +330 -0
- package/dist/discord/normalization.js.map +1 -0
- package/dist/discord/rateLimit.d.ts +9 -0
- package/dist/discord/rateLimit.js +11 -0
- package/dist/discord/rateLimit.js.map +1 -0
- package/dist/orchestration/context.d.ts +85 -0
- package/dist/orchestration/context.js +200 -0
- package/dist/orchestration/context.js.map +1 -0
- package/dist/orchestration/decisions.d.ts +52 -0
- package/dist/orchestration/decisions.js +61 -0
- package/dist/orchestration/decisions.js.map +1 -0
- package/dist/orchestration/messageSplit.d.ts +6 -0
- package/dist/orchestration/messageSplit.js +118 -0
- package/dist/orchestration/messageSplit.js.map +1 -0
- package/dist/orchestration/ocr.d.ts +43 -0
- package/dist/orchestration/ocr.js +504 -0
- package/dist/orchestration/ocr.js.map +1 -0
- package/dist/orchestration/ocrPackages.d.ts +24 -0
- package/dist/orchestration/ocrPackages.js +85 -0
- package/dist/orchestration/ocrPackages.js.map +1 -0
- package/dist/orchestration/promptBlocks.d.ts +28 -0
- package/dist/orchestration/promptBlocks.js +232 -0
- package/dist/orchestration/promptBlocks.js.map +1 -0
- package/dist/orchestration/replyQuote.d.ts +7 -0
- package/dist/orchestration/replyQuote.js +198 -0
- package/dist/orchestration/replyQuote.js.map +1 -0
- package/dist/orchestration/reviewer.d.ts +5 -0
- package/dist/orchestration/reviewer.js +5 -0
- package/dist/orchestration/reviewer.js.map +1 -0
- package/dist/orchestration/runtime.d.ts +152 -0
- package/dist/orchestration/runtime.js +3535 -0
- package/dist/orchestration/runtime.js.map +1 -0
- package/dist/orchestration/session.d.ts +30 -0
- package/dist/orchestration/session.js +41 -0
- package/dist/orchestration/session.js.map +1 -0
- package/dist/orchestration/stageManager.d.ts +42 -0
- package/dist/orchestration/stageManager.js +50 -0
- package/dist/orchestration/stageManager.js.map +1 -0
- package/dist/providers/catalog.d.ts +6 -0
- package/dist/providers/catalog.js +212 -0
- package/dist/providers/catalog.js.map +1 -0
- package/dist/providers/pipelines.d.ts +13 -0
- package/dist/providers/pipelines.js +2388 -0
- package/dist/providers/pipelines.js.map +1 -0
- package/dist/providers/types.d.ts +91 -0
- package/dist/providers/types.js +2 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/shared/queryLog.d.ts +39 -0
- package/dist/shared/queryLog.js +80 -0
- package/dist/shared/queryLog.js.map +1 -0
- package/dist/shared/schemas/common.d.ts +21 -0
- package/dist/shared/schemas/common.js +27 -0
- package/dist/shared/schemas/common.js.map +1 -0
- package/dist/shared/schemas/config.d.ts +57 -0
- package/dist/shared/schemas/config.js +49 -0
- package/dist/shared/schemas/config.js.map +1 -0
- package/dist/shared/schemas/domain.d.ts +825 -0
- package/dist/shared/schemas/domain.js +444 -0
- package/dist/shared/schemas/domain.js.map +1 -0
- package/dist/storage/atomic.d.ts +6 -0
- package/dist/storage/atomic.js +60 -0
- package/dist/storage/atomic.js.map +1 -0
- package/dist/storage/errors.d.ts +12 -0
- package/dist/storage/errors.js +23 -0
- package/dist/storage/errors.js.map +1 -0
- package/dist/storage/locks.d.ts +9 -0
- package/dist/storage/locks.js +42 -0
- package/dist/storage/locks.js.map +1 -0
- package/dist/storage/storageService.d.ts +25 -0
- package/dist/storage/storageService.js +66 -0
- package/dist/storage/storageService.js.map +1 -0
- package/dist-frontend/assets/index-B2bB3_2r.js +39 -0
- package/dist-frontend/assets/index-B2bB3_2r.js.map +1 -0
- package/dist-frontend/assets/index-Dj1L8Px-.css +1 -0
- package/dist-frontend/index.html +14 -0
- package/docs/api.md +162 -0
- package/docs/old-orchestrator-prompt.md +123 -0
- package/package.json +81 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;--bg-app:#0c0e12;--bg-sidebar:#0f1217;--bg-panel:#12161d;--bg-panel-hover:#161b24;--bg-input:#0d1116;--bg-elevated:#181d27;--border-subtle:#1c222d;--border-default:#232b39;--border-strong:#2c3647;--border-focus:#3d6cf2;--text-primary:#e7ecf3;--text-secondary:#a4adbd;--text-muted:#6b7587;--text-disabled:#4a5161;--accent:#5b8def;--accent-strong:#4a78dd;--accent-text:#fff;--ok:#2fbb70;--ok-bg:#2fbb701f;--warn:#f3a83a;--warn-bg:#f3a83a24;--err:#ef5b5b;--err-bg:#ef5b5b24;--info:#58a8df;--info-bg:#58a8df1f;--neutral:#6b7587;--neutral-bg:#6b758729;--sidebar-w:224px;--topbar-h:48px;--radius-sm:4px;--radius-md:6px;--radius-lg:8px;--sp-1:4px;--sp-2:8px;--sp-3:12px;--sp-4:16px;--sp-5:20px;--sp-6:24px;--sp-8:32px;--font-sans:-apple-system, BlinkMacSystemFont, "Inter", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;--font-mono:"SF Mono", "JetBrains Mono", Menlo, Monaco, Consolas, "Liberation Mono", monospace;--fs-xs:11px;--fs-sm:12px;--fs-md:13px;--fs-lg:15px;--fs-xl:18px;--fs-2xl:22px;--shadow-1:0 1px 0 #0006;--shadow-modal:0 16px 48px #00000080}*,:before,:after{box-sizing:border-box}html,body,#root{background:var(--bg-app);height:100%;color:var(--text-primary);font-family:var(--font-sans);font-size:var(--fs-md);-webkit-font-smoothing:antialiased;text-rendering:optimizelegibility;margin:0;line-height:1.45}button,input,select,textarea{font-family:inherit;font-size:inherit;color:inherit}a{color:var(--accent);text-decoration:none}a:hover{text-decoration:underline}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-thumb{background:#1d232e;border-radius:8px}::-webkit-scrollbar-thumb:hover{background:#2a313e}::-webkit-scrollbar-track{background:0 0}.app-shell{grid-template-columns:var(--sidebar-w) 1fr;grid-template-rows:var(--topbar-h) 1fr;grid-template-areas:"sidebar topbar""sidebar main";height:100vh;min-height:100vh;display:grid;overflow:hidden}.sidebar{background:var(--bg-sidebar);border-right:1px solid var(--border-subtle);flex-direction:column;grid-area:sidebar;min-width:0;display:flex}.brand{align-items:center;gap:var(--sp-2);padding:var(--sp-4);height:var(--topbar-h);border-bottom:1px solid var(--border-subtle);font-weight:600;font-size:var(--fs-md);letter-spacing:.2px;display:flex}.brand-mark{border-radius:var(--radius-sm);color:#fff;background:linear-gradient(135deg,#5b8def,#2fbb70);justify-content:center;align-items:center;width:22px;height:22px;font-size:12px;font-weight:700;display:inline-flex}.nav{padding:var(--sp-2);flex-direction:column;gap:2px;display:flex;overflow-y:auto}.nav-section-label{font-size:var(--fs-xs);color:var(--text-muted);text-transform:uppercase;letter-spacing:.06em;padding:var(--sp-3) var(--sp-3) var(--sp-1)}.nav-item{align-items:center;gap:var(--sp-2);padding:7px var(--sp-3);border-radius:var(--radius-md);color:var(--text-secondary);cursor:pointer;text-align:left;width:100%;font-size:var(--fs-md);background:0 0;border:none;height:30px;line-height:1.2;display:flex}.nav-item:hover{background:var(--bg-panel-hover);color:var(--text-primary)}.nav-item.active{background:var(--bg-panel);color:var(--text-primary);box-shadow:inset 0 0 0 1px var(--border-default)}.nav-item .icon{opacity:.85;flex-shrink:0;width:16px;height:16px}.sidebar-footer{padding:var(--sp-3);border-top:1px solid var(--border-subtle);font-size:var(--fs-xs);color:var(--text-muted);flex-direction:column;gap:4px;margin-top:auto;display:flex}.topbar{align-items:center;gap:var(--sp-3);padding:0 var(--sp-4);border-bottom:1px solid var(--border-subtle);background:var(--bg-app);height:var(--topbar-h);grid-area:topbar;display:flex}.topbar h1{font-size:var(--fs-md);color:var(--text-primary);margin:0;font-weight:600}.topbar-spacer{flex:1}.topbar-status{align-items:center;gap:var(--sp-3);display:flex}.main{padding:var(--sp-6);grid-area:main;min-width:0;overflow-y:auto}.view-header{justify-content:space-between;align-items:flex-end;gap:var(--sp-4);margin-bottom:var(--sp-5);flex-wrap:wrap;display:flex}.view-title{font-size:var(--fs-xl);margin:0 0 4px;font-weight:600}.view-subtitle{color:var(--text-muted);font-size:var(--fs-sm);margin:0}.view-actions{gap:var(--sp-2);flex-wrap:wrap;display:flex}.panel{background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:var(--radius-lg);padding:var(--sp-4)}.panel-header{margin-bottom:var(--sp-3);justify-content:space-between;align-items:center;display:flex}.panel-title{font-weight:600;font-size:var(--fs-md);color:var(--text-primary);margin:0}.panel-subtitle{color:var(--text-muted);font-size:var(--fs-sm)}.section{margin-bottom:var(--sp-8)}.section-header{justify-content:space-between;align-items:baseline;gap:var(--sp-3);padding-bottom:var(--sp-2);margin-bottom:var(--sp-4);border-bottom:1px solid var(--border-subtle);display:flex}.section-title{font-size:var(--fs-lg);margin:0;font-weight:600}.section-description{color:var(--text-muted);font-size:var(--fs-sm)}.grid{gap:var(--sp-3);display:grid}.grid-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-4{grid-template-columns:repeat(4,minmax(0,1fr))}@media (max-width:1080px){.grid-4,.grid-3{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width:720px){.grid-2,.grid-3,.grid-4{grid-template-columns:1fr}}.field{flex-direction:column;gap:6px;min-width:0;display:flex}.field label,label.field-label{font-size:var(--fs-sm);color:var(--text-secondary)}.field-hint{font-size:var(--fs-xs);color:var(--text-muted)}.input,.textarea,.select{background:var(--bg-input);border:1px solid var(--border-default);width:100%;color:var(--text-primary);border-radius:var(--radius-md);outline:none;height:32px;padding:7px 10px;transition:border-color .15s,box-shadow .15s}.input:focus,.textarea:focus,.select:focus{border-color:var(--border-focus);box-shadow:0 0 0 2px #3d6cf22e}.textarea{resize:vertical;height:auto;min-height:80px;font-family:var(--font-mono);font-size:var(--fs-sm);padding:8px 10px;line-height:1.45}.input.code{font-family:var(--font-mono);font-size:var(--fs-sm)}.btn{border-radius:var(--radius-md);background:var(--bg-elevated);height:30px;color:var(--text-primary);border:1px solid var(--border-default);cursor:pointer;font-size:var(--fs-sm);white-space:nowrap;justify-content:center;align-items:center;gap:6px;padding:0 12px;font-weight:500;transition:background-color .15s,border-color .15s,color .15s;display:inline-flex}.btn:hover{background:var(--bg-panel-hover);border-color:var(--border-strong)}.btn:disabled{opacity:.55;cursor:not-allowed}.btn.primary{background:var(--accent);border-color:var(--accent);color:var(--accent-text)}.btn.primary:hover{background:var(--accent-strong);border-color:var(--accent-strong)}.btn.danger{border-color:var(--err);color:var(--err);background:0 0}.btn.danger:hover{background:var(--err-bg);border-color:var(--err)}.btn.ghost{background:0 0;border-color:#0000}.btn.ghost:hover{background:var(--bg-panel-hover);border-color:var(--border-default)}.btn.sm{height:26px;font-size:var(--fs-xs);padding:0 9px}.btn .icon{width:14px;height:14px}.pill{height:22px;font-size:var(--fs-xs);background:var(--neutral-bg);color:var(--text-secondary);white-space:nowrap;border:1px solid #0000;border-radius:999px;align-items:center;gap:6px;padding:0 8px;font-weight:500;display:inline-flex}.pill.ok{background:var(--ok-bg);color:var(--ok)}.pill.warn{background:var(--warn-bg);color:var(--warn)}.pill.err{background:var(--err-bg);color:var(--err)}.pill.info{background:var(--info-bg);color:var(--info)}.pill.dot:before{content:"";background:currentColor;border-radius:999px;width:6px;height:6px}.table-wrap{border:1px solid var(--border-subtle);border-radius:var(--radius-lg);background:var(--bg-panel);overflow:hidden}table.data-table{border-collapse:collapse;width:100%;font-size:var(--fs-sm)}.data-table th,.data-table td{text-align:left;border-bottom:1px solid var(--border-subtle);vertical-align:middle;white-space:nowrap;padding:8px 12px}.data-table th{background:var(--bg-elevated);color:var(--text-secondary);font-weight:500;font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.04em;height:32px}.data-table tbody tr:hover{background:var(--bg-panel-hover)}.data-table tbody tr:last-child td{border-bottom:none}.data-table td.wrap{white-space:normal}.data-table td.right,.data-table th.right{text-align:right}.data-table td .cell-actions{gap:4px;display:inline-flex}.stat-row{gap:var(--sp-3);margin-bottom:var(--sp-5);grid-template-columns:repeat(auto-fill,minmax(180px,1fr));display:grid}.stat{border:1px solid var(--border-subtle);border-radius:var(--radius-lg);padding:var(--sp-3) var(--sp-4);background:var(--bg-panel);flex-direction:column;gap:4px;min-width:0;display:flex}.stat-label{font-size:var(--fs-xs);color:var(--text-muted);text-transform:uppercase;letter-spacing:.04em}.stat-value{font-size:var(--fs-xl);color:var(--text-primary);font-variant-numeric:tabular-nums;font-weight:600;line-height:1.1}.stat-foot{font-size:var(--fs-xs);color:var(--text-muted)}.toolbar{align-items:center;gap:var(--sp-2);padding:var(--sp-2) 0;margin-bottom:var(--sp-3);flex-wrap:wrap;display:flex}.toolbar .spacer{flex:1}.toolbar .label{font-size:var(--fs-xs);color:var(--text-muted);margin-right:4px}.empty{text-align:center;padding:var(--sp-8) var(--sp-4);color:var(--text-muted);border:1px dashed var(--border-default);border-radius:var(--radius-lg);background:var(--bg-panel);flex-direction:column;justify-content:center;align-items:center;display:flex}.empty .icon-lg{width:28px;height:28px;margin-bottom:var(--sp-2);opacity:.7}.empty .empty-title{color:var(--text-primary);margin-bottom:4px;font-weight:500}.empty .empty-help{font-size:var(--fs-sm);max-width:380px}.notice{align-items:flex-start;gap:var(--sp-2);padding:10px var(--sp-3);border-radius:var(--radius-md);font-size:var(--fs-sm);border:1px solid var(--border-subtle);display:flex}.notice.ok{background:var(--ok-bg);color:#b5e8c8;border-color:#2fbb7059}.notice.warn{background:var(--warn-bg);color:#f6dcad;border-color:#f3a83a59}.notice.err{background:var(--err-bg);color:#f6c2c2;border-color:#ef5b5b59}.notice.info{background:var(--info-bg);color:#c5e0f3;border-color:#58a8df59}.notice .icon{flex-shrink:0;width:16px;height:16px;margin-top:1px}.modal-backdrop{-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);z-index:50;padding:var(--sp-4);background:#080a0e99;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.modal{background:var(--bg-panel);border:1px solid var(--border-default);border-radius:var(--radius-lg);width:100%;max-width:560px;max-height:calc(100vh - 64px);box-shadow:var(--shadow-modal);flex-direction:column;display:flex;overflow:hidden}.modal.wide{max-width:760px}.modal-header{padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--border-subtle);justify-content:space-between;align-items:center;font-weight:600;display:flex}.modal-body{padding:var(--sp-4);gap:var(--sp-3);flex-direction:column;display:flex;overflow-y:auto}.modal-footer{padding:var(--sp-3) var(--sp-4);border-top:1px solid var(--border-subtle);justify-content:flex-end;gap:var(--sp-2);display:flex}.code-block{font-family:var(--font-mono);font-size:var(--fs-sm);background:var(--bg-input);border:1px solid var(--border-subtle);border-radius:var(--radius-md);white-space:pre;color:var(--text-primary);padding:10px 12px;overflow-x:auto}.kv{font-size:var(--fs-sm);grid-template-columns:160px 1fr;gap:6px 16px;display:grid}.kv .k{color:var(--text-muted)}.kv .v{color:var(--text-primary);font-variant-numeric:tabular-nums;word-break:break-word}@media (max-width:720px){.kv{grid-template-columns:1fr}}.tag{background:var(--bg-elevated);border:1px solid var(--border-subtle);border-radius:var(--radius-sm);font-size:var(--fs-xs);color:var(--text-secondary);font-family:var(--font-mono);align-items:center;gap:4px;padding:2px 6px;display:inline-flex}.row{align-items:center;gap:var(--sp-2);flex-wrap:wrap;display:flex}.row.tight{gap:4px}.checkbox-chip{border:1px solid var(--border-subtle);border-radius:var(--radius-sm);background:var(--bg-elevated);min-height:24px;color:var(--text-secondary);font-size:var(--fs-xs);white-space:nowrap;align-items:center;gap:4px;padding:2px 6px;display:inline-flex}.checkbox-chip input{width:13px;height:13px;margin:0}.spacer{flex:1}.divider{background:var(--border-subtle);height:1px;margin:var(--sp-3) 0;border:none}.log-list{background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:var(--radius-lg);padding:var(--sp-2);font-family:var(--font-mono);font-size:var(--fs-sm);flex-direction:column;gap:2px;max-height:60vh;display:flex;overflow-y:auto}.log-line{gap:var(--sp-3);padding:4px var(--sp-2);border-radius:4px;grid-template-columns:78px 70px 90px 1fr;align-items:baseline;display:grid}.log-line:hover{background:var(--bg-panel-hover)}.log-line .ts{color:var(--text-muted)}.log-line .lvl{text-transform:uppercase;font-weight:600;font-size:var(--fs-xs)}.log-line .src{color:var(--text-secondary)}.log-line .msg{color:var(--text-primary);white-space:pre-wrap;word-break:break-word}.log-line .lvl.info{color:var(--info)}.log-line .lvl.warn{color:var(--warn)}.log-line .lvl.err{color:var(--err)}.log-line .lvl.ok{color:var(--ok)}.toggle{cursor:pointer;-webkit-user-select:none;user-select:none;align-items:center;gap:8px;display:inline-flex}.toggle input{appearance:none;background:var(--bg-elevated);border:1px solid var(--border-default);cursor:pointer;border-radius:999px;flex-shrink:0;width:30px;height:18px;margin:0;transition:background-color .15s,border-color .15s;position:relative}.toggle input:after{content:"";background:var(--text-secondary);border-radius:50%;width:12px;height:12px;transition:transform .15s,background-color .15s;position:absolute;top:2px;left:2px}.toggle input:checked{background:var(--accent);border-color:var(--accent)}.toggle input:checked:after{background:#fff;transform:translate(12px)}.provider-row{gap:var(--sp-4);padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--border-subtle);grid-template-columns:1fr auto;align-items:center;display:grid}.provider-row:last-child{border-bottom:none}.provider-row .meta{flex-direction:column;gap:4px;min-width:0;display:flex}.provider-row .name{font-weight:600;font-size:var(--fs-md)}.provider-row .sub{color:var(--text-muted);font-size:var(--fs-xs)}.provider-row .actions{gap:var(--sp-2);align-items:center;display:flex}.model-grid{gap:var(--sp-3);grid-template-columns:repeat(auto-fill,minmax(280px,1fr));display:grid}.model-card{border:1px solid var(--border-subtle);border-radius:var(--radius-lg);padding:var(--sp-3);background:var(--bg-panel);flex-direction:column;gap:6px;min-width:0;display:flex}.model-card .row1{justify-content:space-between;align-items:baseline;gap:var(--sp-2);display:flex}.model-card .title{font-weight:600;font-size:var(--fs-md);margin:0}.model-card .id{font-family:var(--font-mono);font-size:var(--fs-xs);color:var(--text-muted)}.model-card .caps{flex-wrap:wrap;gap:4px;margin-top:4px;display:flex}.stepper{gap:var(--sp-3);flex-direction:column;display:flex}.step{gap:var(--sp-3);border:1px solid var(--border-subtle);border-radius:var(--radius-lg);padding:var(--sp-3) var(--sp-4);background:var(--bg-panel);grid-template-columns:28px 1fr;align-items:flex-start;display:grid}.step.complete{border-color:#2fbb7066}.step .num{background:var(--bg-elevated);border:1px solid var(--border-default);width:24px;height:24px;color:var(--text-secondary);font-size:var(--fs-sm);border-radius:999px;flex-shrink:0;justify-content:center;align-items:center;font-weight:600;display:inline-flex}.step.complete .num{background:var(--ok-bg);border-color:var(--ok);color:var(--ok)}.step .body{gap:var(--sp-2);flex-direction:column;min-width:0;display:flex}.step .head{justify-content:space-between;align-items:baseline;gap:var(--sp-3);display:flex}.step .step-title{font-weight:600;font-size:var(--fs-md)}.step .step-desc{color:var(--text-muted);font-size:var(--fs-sm)}.skeleton{background:linear-gradient(90deg, var(--bg-panel) 0%, var(--bg-panel-hover) 50%, var(--bg-panel) 100%);border-radius:var(--radius-md);background-size:200% 100%;height:14px;animation:1.4s infinite skel}@keyframes skel{0%{background-position:200% 0}to{background-position:-200% 0}}@media (max-width:880px){.app-shell{grid-template-columns:1fr;grid-template-areas:"topbar""main";grid-template-rows:var(--topbar-h) 1fr}.sidebar{display:none}.sidebar.open{z-index:40;border-right:1px solid var(--border-default);width:240px;display:flex;position:fixed;top:0;bottom:0;left:0}.menu-btn{display:inline-flex}}.menu-btn,.menu-backdrop{display:none}.menu-backdrop.open{z-index:30;background:#00000073;display:block;position:fixed;inset:0}.scroll-shadow{position:relative}.prompt-layout-lanes{gap:var(--sp-3);grid-template-columns:repeat(3,1fr);align-items:start;display:grid}@media (max-width:900px){.prompt-layout-lanes{grid-template-columns:1fr}}.prompt-lane{gap:var(--sp-2);background:var(--bg-panel);border:1px solid var(--border-subtle);border-radius:var(--radius-lg);padding:var(--sp-3);flex-direction:column;display:flex}.prompt-lane-head{flex-direction:column;gap:2px;display:flex}.prompt-lane-title{font-size:var(--fs-sm);color:var(--text-primary);font-weight:600}.prompt-lane-body{gap:var(--sp-2);flex-direction:column;min-height:48px;display:flex}.prompt-lane-empty{border:1px dashed var(--border-default);border-radius:var(--radius-md);padding:var(--sp-3);text-align:center;font-size:var(--fs-xs);color:var(--text-muted)}.prompt-card{align-items:center;gap:var(--sp-2);background:var(--bg-elevated);border:1px solid var(--border-default);border-radius:var(--radius-md);padding:var(--sp-2);display:flex}.prompt-card.is-disabled{opacity:.5}.prompt-card.is-dragging{box-shadow:var(--shadow-modal);border-color:var(--border-focus)}.prompt-card-main{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.prompt-card-label{font-family:var(--font-mono);font-size:var(--fs-sm);color:var(--text-primary);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.prompt-drag{color:var(--text-muted);cursor:grab;background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;padding:2px;display:inline-flex}.prompt-drag:active{cursor:grabbing}.prompt-drag .icon{width:14px;height:14px}.prompt-group{background:var(--bg-panel-hover);border:1px solid var(--border-strong);border-radius:var(--radius-md);padding:var(--sp-2);gap:var(--sp-2);flex-direction:column;display:flex}.prompt-group.is-disabled{opacity:.5}.prompt-group-head{align-items:center;gap:4px;display:flex}.prompt-group-tag-prefix{font-family:var(--font-mono);color:var(--text-muted)}.prompt-group-tag-input{font-family:var(--font-mono);font-size:var(--fs-sm);flex:1;min-width:0;height:26px}.prompt-group-actions{flex-shrink:0;align-items:center;gap:4px;display:flex}.icon-btn{width:26px;height:26px;padding:0}.prompt-group-body{gap:var(--sp-2);min-height:40px;padding-left:var(--sp-2);border-left:2px solid var(--border-default);flex-direction:column;display:flex}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<meta name="color-scheme" content="dark light" />
|
|
7
|
+
<title>Discord Waifus</title>
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-B2bB3_2r.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-Dj1L8Px-.css">
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<div id="root"></div>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
package/docs/api.md
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# Discord Waifus Backend API
|
|
2
|
+
|
|
3
|
+
Base URL defaults to `http://127.0.0.1:3888`.
|
|
4
|
+
|
|
5
|
+
All frontend code should use this HTTP API. It should not read `~/.dc-waifus` or `DC_WAIFUS_HOME` directly.
|
|
6
|
+
|
|
7
|
+
## Runtime
|
|
8
|
+
|
|
9
|
+
- `GET /api/health`
|
|
10
|
+
- `GET /api/status`
|
|
11
|
+
- `GET /api/runtime`
|
|
12
|
+
- `POST /api/runtime/pause`
|
|
13
|
+
- `POST /api/runtime/resume`
|
|
14
|
+
- `POST /api/runtime/reload`
|
|
15
|
+
- `POST /api/runtime/trigger/orchestrator`
|
|
16
|
+
- `POST /api/runtime/trigger/stage-manager`
|
|
17
|
+
- `GET /api/diagnostics/bundle`
|
|
18
|
+
- `GET /api/events`
|
|
19
|
+
|
|
20
|
+
`/api/events` is an SSE endpoint. It emits a runtime snapshot and heartbeat events.
|
|
21
|
+
|
|
22
|
+
When Discord auto-connect is enabled and an orchestrator token is saved, the backend starts the runtime loop:
|
|
23
|
+
|
|
24
|
+
1. Discord `messageCreate` events discover guilds/channels and trigger enabled channel sessions.
|
|
25
|
+
2. The runtime cancels any active orchestrator/waifu request for that channel when a newer message arrives.
|
|
26
|
+
3. It fetches fresh Discord history before each orchestrator, waifu, and stage-manager model request.
|
|
27
|
+
4. Orchestrator decisions are validated, written to history, and executed.
|
|
28
|
+
5. Waifus answer in selected order using their configured model and bot.
|
|
29
|
+
6. `no_reply` decisions schedule bounded retriggers.
|
|
30
|
+
7. Stage-manager runs are background tasks and write memory/history through the shared memory lock.
|
|
31
|
+
|
|
32
|
+
`POST /api/runtime/trigger/orchestrator` and `POST /api/runtime/trigger/stage-manager` accept optional JSON bodies with `guildId` and `channelId` to run the real channel pipeline manually. Without a target channel they only record a manual history entry.
|
|
33
|
+
|
|
34
|
+
Normal configuration changes apply at runtime. `PUT /api/config`, `PUT /api/discord-bots`, and `POST /api/runtime/reload` rebuild Discord clients and the runtime orchestrator in-process without restarting HTTP. Only HTTP host/port changes require the next process start.
|
|
35
|
+
|
|
36
|
+
During startup, HTTP binds before Discord auto-connect completes. `/api/status` and `/api/runtime` set optional `discord.connecting` while Discord login is in progress. If Discord auto-connect fails with a transient DNS or network error, the backend keeps Discord offline and retries automatically. Retry metadata is optional: `retrying`, `retryAttempt`, `nextRetryAt`, `lastError`, and `lastErrorAt`.
|
|
37
|
+
|
|
38
|
+
## Config
|
|
39
|
+
|
|
40
|
+
- `GET /api/config`
|
|
41
|
+
- `PUT /api/config`
|
|
42
|
+
- `POST /api/cache/ocr/clear`
|
|
43
|
+
- `GET /api/discord-bots`
|
|
44
|
+
- `PUT /api/discord-bots`
|
|
45
|
+
- `GET /api/orchestrator/config`
|
|
46
|
+
- `PUT /api/orchestrator/config`
|
|
47
|
+
- `GET /api/orchestrator/history`
|
|
48
|
+
- `GET /api/stage-manager/config`
|
|
49
|
+
- `PUT /api/stage-manager/config`
|
|
50
|
+
- `GET /api/stage-manager/history`
|
|
51
|
+
|
|
52
|
+
Config is backed by `config.toml` under the data root. Default config:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"schemaVersion": 1,
|
|
57
|
+
"http": { "host": "127.0.0.1", "port": 3888 },
|
|
58
|
+
"runtime": { "autoConnectDiscord": true, "paused": false },
|
|
59
|
+
"frontend": {},
|
|
60
|
+
"ocr": {
|
|
61
|
+
"enabled": true,
|
|
62
|
+
"engine": "auto",
|
|
63
|
+
"cacheTtlHours": 24,
|
|
64
|
+
"timeoutMs": 1500,
|
|
65
|
+
"maxImageBytes": 8388608,
|
|
66
|
+
"maxImagesPerModelCall": 4,
|
|
67
|
+
"maxTextCharsPerImage": 1500
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
OCR is used only as a fallback for models that are not marked as vision-capable. `engine = "auto"` tries native OS OCR first where supported (Apple Vision on macOS), then the bundled WebAssembly Tesseract (`tesseract.js`, shipped with the package and working offline on every platform), then an explicit system Tesseract fallback. Valid engine values are `auto`, `apple-vision`, `bundled-tesseract`, and `system-tesseract`; legacy `tesseract` configs load as `system-tesseract`. Temporary image downloads live under `app/tmp/ocr`; cached text results live under `app/cache/ocr` and expire by `cacheTtlHours`. `POST /api/cache/ocr/clear` removes OCR cache and temporary OCR files.
|
|
73
|
+
|
|
74
|
+
## Providers And Models
|
|
75
|
+
|
|
76
|
+
- `GET /api/providers`
|
|
77
|
+
- `PUT /api/providers/:providerId/credentials`
|
|
78
|
+
- `GET /api/models`
|
|
79
|
+
|
|
80
|
+
Provider IDs are `xai`, `deepseek`, `anthropic`, `openai`, and `zai`.
|
|
81
|
+
|
|
82
|
+
Credential writes accept:
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"revision": 0,
|
|
87
|
+
"apiKey": "secret",
|
|
88
|
+
"label": "optional label"
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Responses never include raw API keys. They include `configured`, optional `label`, `updatedAt`, and `keyHint`.
|
|
93
|
+
|
|
94
|
+
Discord bot config responses never include raw bot tokens. They include `tokenConfigured` and `tokenHint`. Sending a bot update without a `token` preserves the saved token.
|
|
95
|
+
|
|
96
|
+
## Waifus
|
|
97
|
+
|
|
98
|
+
- `GET /api/waifus`
|
|
99
|
+
- `POST /api/waifus`
|
|
100
|
+
- `GET /api/waifus/:waifuId`
|
|
101
|
+
- `PUT /api/waifus/:waifuId`
|
|
102
|
+
- `DELETE /api/waifus/:waifuId`
|
|
103
|
+
- `POST /api/waifus/:waifuId/assets/pfp`
|
|
104
|
+
- `POST /api/waifus/:waifuId/assets/banner`
|
|
105
|
+
|
|
106
|
+
`PUT` and `DELETE` require either a `revision` body field or an `If-Match` header. Stale writes return `409 Conflict` with the latest server copy.
|
|
107
|
+
|
|
108
|
+
Asset uploads accept raw `image/png`, `image/jpeg`, `image/webp`, or `image/gif` request bodies up to 8 MB. Files are stored in `user/waifus/<waifu-id>/`.
|
|
109
|
+
|
|
110
|
+
## Servers
|
|
111
|
+
|
|
112
|
+
- `GET /api/servers`
|
|
113
|
+
- `PUT /api/servers/:guildId`
|
|
114
|
+
- `GET /api/servers/:guildId/members`
|
|
115
|
+
- `POST /api/servers/:guildId/members/refresh`
|
|
116
|
+
- `GET /api/servers/:guildId/emojis`
|
|
117
|
+
- `POST /api/servers/:guildId/emojis/refresh`
|
|
118
|
+
- `PUT /api/servers/:guildId/channels/:channelId`
|
|
119
|
+
|
|
120
|
+
Member and emoji refresh endpoints use the configured orchestrator bot token. Member refresh requires Discord permissions/intents that allow member listing. Emoji refresh caches guild custom emojis in `user/servers/<guild-id>/emojis.json`.
|
|
121
|
+
|
|
122
|
+
## Memories
|
|
123
|
+
|
|
124
|
+
- `GET /api/memories`
|
|
125
|
+
- `POST /api/memories`
|
|
126
|
+
- `PUT /api/memories/:memoryId`
|
|
127
|
+
- `DELETE /api/memories/:memoryId`
|
|
128
|
+
|
|
129
|
+
Memory writes use the memory store revision. Stage-manager and UI memory edits must share this same lock and revision flow.
|
|
130
|
+
|
|
131
|
+
## Conflict Semantics
|
|
132
|
+
|
|
133
|
+
Editable JSON records include:
|
|
134
|
+
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"schemaVersion": 1,
|
|
138
|
+
"revision": 0,
|
|
139
|
+
"updatedAt": "2026-05-15T00:00:00.000Z"
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Overwriting or destructive requests should send the last seen `revision`. If the record changed, the backend returns:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"error": "Conflict",
|
|
148
|
+
"message": "Record has changed since it was read.",
|
|
149
|
+
"latest": {}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Discord Text Contract
|
|
154
|
+
|
|
155
|
+
Model context must not expose raw Discord IDs.
|
|
156
|
+
|
|
157
|
+
- Incoming `<@623587468920134>` and `<@!623587468920134>` become `<@DisplayName>`.
|
|
158
|
+
- Incoming `<:cutecat:327469812364>` becomes `<:cutecat:>`.
|
|
159
|
+
- Incoming `<a:dance:327469812364>` becomes `<a:dance:>`.
|
|
160
|
+
- Model output is resolved back to Discord syntax only when the cached member or emoji match is safe.
|
|
161
|
+
- Ambiguous user mentions are left unpinged and returned with warnings.
|
|
162
|
+
- `allowed_mentions` is restricted to explicitly resolved user IDs. Role, everyone, and here mentions are not enabled by default.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Old Orchestrator System Prompt
|
|
2
|
+
|
|
3
|
+
Recovered from commit `7d8c219` ("Fix channel creation flow") — the last commit before `356fbb1 chore: empty repository`.
|
|
4
|
+
|
|
5
|
+
Source: `packages/backend/src/prompt-builder.ts` → `PromptBuilder.buildOrchestratorSystemPrompt()`.
|
|
6
|
+
|
|
7
|
+
Dynamic fields are shown as `{…}` placeholders; the optional sections only appear when their trigger condition is met.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
You are the Orchestrator for a Discord group chat inhabited by AI waifus (characters).
|
|
13
|
+
Your job is to direct the room: decide which waifu(s) should respond next, in what order, or whether nobody should respond right now.
|
|
14
|
+
You must call the orchestrator_decision tool exactly once with your final decision.
|
|
15
|
+
|
|
16
|
+
## Active Waifus
|
|
17
|
+
{waifuBlock — per waifu:
|
|
18
|
+
### {name} (ID: {id})
|
|
19
|
+
- Personality: {description}
|
|
20
|
+
- Traits: {comma-separated, or "none listed"}
|
|
21
|
+
- Speech Patterns: {comma-separated, or "none listed"}
|
|
22
|
+
- Likes: {comma-separated, or "none listed"}
|
|
23
|
+
- Dislikes: {comma-separated, or "none listed"}
|
|
24
|
+
- Schedule: Sleeps {sleep.start}-{sleep.end} UTC. Busy {busy.start}-{busy.end} UTC ({busy.reason}).
|
|
25
|
+
- Relationships: {JSON map}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
## Current Time
|
|
29
|
+
{currentTimeUTC} (UTC)
|
|
30
|
+
|
|
31
|
+
## Decision Rules
|
|
32
|
+
1. Be natural. Real group chats do not require everyone to reply every time.
|
|
33
|
+
2. You are allowed to shape pacing, tension, comedy, interruption, silence, and escalation. Treat the room like a living scene, not a turn-taking queue.
|
|
34
|
+
3. Mentions, quotes, relationships, reactions, timestamps, and recent momentum are all useful signals, but none of them are hard rules.
|
|
35
|
+
4. Always pay special attention to the latest 10 messages. They are the strongest signal for what the room is currently doing, who may have been overlooked, and whether a loop is starting to form.
|
|
36
|
+
5. Sleep time, busy time, and consecutive-message heuristics are soft preferences. Break them whenever doing so would clearly improve conversational flow, realism, or enjoyment.
|
|
37
|
+
6. The same waifu may speak again, a different waifu may jump in, or multiple waifus may chain if it feels right.
|
|
38
|
+
7. Avoid repetitive follow-ups that merely restate the same beat. Continue only when the next message adds something new.
|
|
39
|
+
8. If a recent user message or direct ping went unnoticed while the room moved on, prefer steering someone to acknowledge it so the chat stays socially inclusive unless silence is clearly more natural.
|
|
40
|
+
9. "no_reply" is valid. If you choose it, set retriggerAfterSeconds to a natural delay between 100 and 28800 seconds.
|
|
41
|
+
10. Use timestamps and pacing. Slow gaps matter.
|
|
42
|
+
11. You may suggest emoji reactions sparingly.
|
|
43
|
+
12. delaySeconds should reflect realistic reading and typing time.
|
|
44
|
+
13. consecutiveWaifuMessages for this context: {consecutiveWaifuMessages}.
|
|
45
|
+
14. replyToMessageId is optional. Leave it null by default.
|
|
46
|
+
15. Most waifu messages should be normal messages, not Discord replies.
|
|
47
|
+
16. Do not set replyToMessageId to the immediately previous message. If a waifu is simply responding to the latest beat, send a normal message instead.
|
|
48
|
+
17. If you are reviving, acknowledging, or directly answering an older user message or direct ping that went overlooked, you should usually set replyToMessageId to that exact message so the response stays anchored to the right person and beat.
|
|
49
|
+
18. Use replyToMessageId only when targeting a specific older message materially improves clarity, isolates a side thread, answers an earlier question, or creates a specific social effect. If you use it, copy an exact message ID from the Recent Chat History.
|
|
50
|
+
19. If you choose reactionEmoji, prefer an exact emoji from the Available Server Emojis list when one fits.
|
|
51
|
+
20. Avoid repeating the same reaction emoji too often when several server emojis are available.
|
|
52
|
+
|
|
53
|
+
## directInteraction
|
|
54
|
+
directInteraction is an optional lightweight visual beat.
|
|
55
|
+
Use it when one waifu should send exactly one server emoji as its own Discord message.
|
|
56
|
+
This creates a large emoji message because the message contains only that one emoji.
|
|
57
|
+
Use it sparingly. It is a rare accent, not default punctuation.
|
|
58
|
+
If the room only needs a quick visible beat, directInteraction can be better than forcing a full text reply.
|
|
59
|
+
It is good for punctuation, surprise, mock horror, approval, interruption, or a quick reaction the whole room should see.
|
|
60
|
+
It is especially worth considering when the latest message is mostly emotional, visual, funny, emoji-like, or does not actually need a full sentence back.
|
|
61
|
+
Do not ignore directInteraction just because a text reply is possible. If one visible emoji beat would satisfy the moment, that can be the better choice.
|
|
62
|
+
At most one directInteraction is allowed per decision.
|
|
63
|
+
You may use directInteraction alone or alongside normal respondingWaifus when it improves pacing.
|
|
64
|
+
Copy the emoji exactly from the Available Server Emojis list.
|
|
65
|
+
Use exactly one server emoji token such as :wtf:.
|
|
66
|
+
Do not use Unicode emoji here.
|
|
67
|
+
Do not put extra text, multiple emojis, or arbitrary strings in directInteraction.emoji.
|
|
68
|
+
If action is no_reply, directInteraction should normally be null.
|
|
69
|
+
|
|
70
|
+
## sceneDirection
|
|
71
|
+
sceneDirection is an invisible director note for that waifu's next message only.
|
|
72
|
+
Use it when the next reply needs stronger steering than replyStyle alone can provide.
|
|
73
|
+
The latest 10 messages are a good place to spot loops early; when you notice one forming, use sceneDirection to cut it before it hardens.
|
|
74
|
+
You may use it to break loops, force a new beat, close a scene, redirect to a new topic, create an interruption, or shift momentum by changing the next objective.
|
|
75
|
+
This is not a personality rewrite and not a long paragraph.
|
|
76
|
+
Keep it short, concrete, and immediately actionable. One short sentence is usually enough.
|
|
77
|
+
When referring to a specific user inside sceneDirection, use that user's actual name from chat history. Do not write generic phrases like "the user" when a specific person is meant.
|
|
78
|
+
Name the intended participants explicitly when the direction involves more than one person.
|
|
79
|
+
Do not use ambiguous group references like "us", "them", "everyone", or implied membership when specific names can be given.
|
|
80
|
+
If the beat is about including or excluding someone, state exactly who is already involved and who should be pulled in.
|
|
81
|
+
sceneDirection does not always need to follow the current mood or flow exactly. It may deliberately start something new when that will improve the scene.
|
|
82
|
+
Use natural bridges when pivoting when possible.
|
|
83
|
+
If multiple waifus respond, each one may receive a different sceneDirection.
|
|
84
|
+
If no special steering is needed, return null.
|
|
85
|
+
|
|
86
|
+
[appended only when server emojis exist]
|
|
87
|
+
## Available Server Emojis
|
|
88
|
+
{space-separated emoji tokens}
|
|
89
|
+
|
|
90
|
+
[appended only when trigger == "idle"]
|
|
91
|
+
## IDLE TRIGGER
|
|
92
|
+
No new messages have been sent recently. The chat has been quiet for a while.
|
|
93
|
+
Would any waifu naturally start a new conversation right now, considering the time of day and their schedule?
|
|
94
|
+
"no_reply" is completely valid if silence feels natural.
|
|
95
|
+
|
|
96
|
+
[appended only when trigger == "waifu_followup"]
|
|
97
|
+
## WAIFU FOLLOW-UP
|
|
98
|
+
The last waifu speaker was: {lastSpeakerWaifuId}.
|
|
99
|
+
Consecutive waifu messages so far: {consecutiveWaifuMessages}.
|
|
100
|
+
A waifu message has already been posted to Discord.
|
|
101
|
+
Decide what happens next from here: the same waifu may continue, another waifu may cut in, multiple waifus may chain naturally, or the room may go quiet.
|
|
102
|
+
Continue only if the next message would add a fresh beat, escalation, interruption, joke, reaction, or emotional shift.
|
|
103
|
+
Do not repeat the same point in slightly different words.
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## How to recover the full original file
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
git show 7d8c219:packages/backend/src/prompt-builder.ts > prompt-builder.ts
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Other relevant files at the same commit:
|
|
115
|
+
|
|
116
|
+
- `packages/backend/src/orchestrator.ts`
|
|
117
|
+
- `packages/backend/src/api/orchestrator.ts`
|
|
118
|
+
- `packages/backend/src/types/orchestrator.ts`
|
|
119
|
+
- `packages/dashboard/src/components/orchestrator-manager.tsx`
|
|
120
|
+
- `packages/dashboard/src/app/orchestrator/page.tsx`
|
|
121
|
+
- `defaults/orchestrator.toml`
|
|
122
|
+
|
|
123
|
+
The pre-wipe tip is `7d8c219`. The "empty repository" commit is `356fbb1`.
|
package/package.json
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@waifucave/discord-waifus",
|
|
3
|
+
"version": "1.5.154",
|
|
4
|
+
"description": "Local Discord waifu orchestrator backend, web UI, and CLI.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"private": false,
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/waifucave/discord-waifus.git"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/waifucave/discord-waifus/issues"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/waifucave/discord-waifus#readme",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"discord",
|
|
17
|
+
"discord-bot",
|
|
18
|
+
"ai",
|
|
19
|
+
"orchestrator",
|
|
20
|
+
"waifu",
|
|
21
|
+
"local-first"
|
|
22
|
+
],
|
|
23
|
+
"bin": {
|
|
24
|
+
"waifus": "./bin/waifus.mjs"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc -p tsconfig.json && npm run build:frontend",
|
|
28
|
+
"build:backend": "tsc -p tsconfig.json",
|
|
29
|
+
"build:frontend": "vite build --config src/frontend/vite.config.ts",
|
|
30
|
+
"dev": "node ./bin/waifus.mjs dev",
|
|
31
|
+
"dev:frontend": "vite --config src/frontend/vite.config.ts",
|
|
32
|
+
"waifus": "node ./bin/waifus.mjs",
|
|
33
|
+
"test": "vitest run",
|
|
34
|
+
"test:watch": "vitest",
|
|
35
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p src/frontend/tsconfig.json --noEmit",
|
|
36
|
+
"prepublishOnly": "npm run test && npm run build",
|
|
37
|
+
"release:beta": "node ./scripts/release.mjs"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"bin/",
|
|
41
|
+
"dist/",
|
|
42
|
+
"dist-frontend/",
|
|
43
|
+
"assets/ocr/",
|
|
44
|
+
"docs/api.md",
|
|
45
|
+
"docs/old-orchestrator-prompt.md",
|
|
46
|
+
"LICENSE",
|
|
47
|
+
"THIRD_PARTY_NOTICES.md",
|
|
48
|
+
"README.md",
|
|
49
|
+
"package.json"
|
|
50
|
+
],
|
|
51
|
+
"publishConfig": {
|
|
52
|
+
"access": "public"
|
|
53
|
+
},
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=20"
|
|
56
|
+
},
|
|
57
|
+
"license": "MIT",
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"@dnd-kit/core": "^6.3.1",
|
|
60
|
+
"@dnd-kit/sortable": "^10.0.0",
|
|
61
|
+
"@dnd-kit/utilities": "^3.2.2",
|
|
62
|
+
"discord.js": "^14.26.4",
|
|
63
|
+
"fastify": "^5.8.5",
|
|
64
|
+
"smol-toml": "^1.6.1",
|
|
65
|
+
"tesseract.js": "7.0.0",
|
|
66
|
+
"tesseract.js-core": "7.0.0",
|
|
67
|
+
"zod": "^4.4.3"
|
|
68
|
+
},
|
|
69
|
+
"devDependencies": {
|
|
70
|
+
"@types/node": "^25.8.0",
|
|
71
|
+
"@types/react": "^19.2.14",
|
|
72
|
+
"@types/react-dom": "^19.2.3",
|
|
73
|
+
"@vitejs/plugin-react": "^5.2.0",
|
|
74
|
+
"lucide-react": "^1.16.0",
|
|
75
|
+
"react": "^19.2.6",
|
|
76
|
+
"react-dom": "^19.2.6",
|
|
77
|
+
"tsx": "^4.22.0",
|
|
78
|
+
"typescript": "^6.0.3",
|
|
79
|
+
"vitest": "^4.1.6"
|
|
80
|
+
}
|
|
81
|
+
}
|