chainlesschain 0.45.2 → 0.45.4
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/package.json +1 -1
- package/src/commands/ui.js +3 -0
- package/src/lib/web-ui-server.js +39 -17
- package/src/lib/ws-session-manager.js +9 -4
package/package.json
CHANGED
package/src/commands/ui.js
CHANGED
|
@@ -15,6 +15,7 @@ import { WSSessionManager } from "../lib/ws-session-manager.js";
|
|
|
15
15
|
import { createWebUIServer } from "../lib/web-ui-server.js";
|
|
16
16
|
import { bootstrap } from "../runtime/bootstrap.js";
|
|
17
17
|
import { findProjectRoot, loadProjectConfig } from "../lib/project-detector.js";
|
|
18
|
+
import { loadConfig } from "../lib/config-manager.js";
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Open a URL in the system default browser (cross-platform).
|
|
@@ -82,9 +83,11 @@ export function registerUiCommand(program) {
|
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
// ── Start WebSocket server ────────────────────────────────────────────
|
|
86
|
+
const appConfig = loadConfig();
|
|
85
87
|
const sessionManager = new WSSessionManager({
|
|
86
88
|
db,
|
|
87
89
|
defaultProjectRoot: projectRoot || process.cwd(),
|
|
90
|
+
config: appConfig,
|
|
88
91
|
});
|
|
89
92
|
|
|
90
93
|
const wsServer = new ChainlessChainWSServer({
|
package/src/lib/web-ui-server.js
CHANGED
|
@@ -55,8 +55,8 @@ function buildHtml({
|
|
|
55
55
|
<title>${escapeHtml(title)}</title>
|
|
56
56
|
<script>window.__CC_CONFIG__ = ${cfg};</script>
|
|
57
57
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
|
|
58
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/
|
|
59
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
|
58
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/9.1.6/marked.min.js" defer></script>
|
|
59
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" defer></script>
|
|
60
60
|
<style>
|
|
61
61
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
62
62
|
|
|
@@ -460,7 +460,7 @@ function buildHtml({
|
|
|
460
460
|
<div id="conn-dot"></div>
|
|
461
461
|
<span id="conn-label">未连接</span>
|
|
462
462
|
</div>
|
|
463
|
-
<span id="version-label">v5.0.2.
|
|
463
|
+
<span id="version-label">v5.0.2.5</span>
|
|
464
464
|
</div>
|
|
465
465
|
</nav>
|
|
466
466
|
|
|
@@ -523,6 +523,7 @@ function buildHtml({
|
|
|
523
523
|
let selectedSessionType = 'agent';
|
|
524
524
|
let pendingQuestionResolve = null;
|
|
525
525
|
let _msgId = 0;
|
|
526
|
+
let _pendingMsgs = []; // buffered while session pending
|
|
526
527
|
const sessions = new Map(); // id → { id, title, type, createdAt }
|
|
527
528
|
|
|
528
529
|
// ── DOM refs ─────────────────────────────────────────────────────────────
|
|
@@ -560,18 +561,24 @@ function buildHtml({
|
|
|
560
561
|
emptyDesc.textContent = '全局模式:未绑定项目,可直接对话或管理项目。';
|
|
561
562
|
}
|
|
562
563
|
|
|
563
|
-
// ── marked.js config
|
|
564
|
-
|
|
565
|
-
marked
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
564
|
+
// ── marked.js config (deferred — called after defer scripts load) ────────
|
|
565
|
+
function initMarked() {
|
|
566
|
+
if (window.marked) {
|
|
567
|
+
try {
|
|
568
|
+
marked.setOptions({
|
|
569
|
+
highlight: (code, lang) => {
|
|
570
|
+
if (window.hljs && lang && hljs.getLanguage(lang)) {
|
|
571
|
+
return hljs.highlight(code, { language: lang }).value;
|
|
572
|
+
}
|
|
573
|
+
return window.hljs ? hljs.highlightAuto(code).value : code;
|
|
574
|
+
},
|
|
575
|
+
breaks: true,
|
|
576
|
+
gfm: true,
|
|
577
|
+
});
|
|
578
|
+
} catch (_) {
|
|
579
|
+
// marked v10+ removed highlight option — ignore, fallback renderer handles it
|
|
580
|
+
}
|
|
581
|
+
}
|
|
575
582
|
}
|
|
576
583
|
|
|
577
584
|
// ── WebSocket ────────────────────────────────────────────────────────────
|
|
@@ -785,6 +792,11 @@ function buildHtml({
|
|
|
785
792
|
}
|
|
786
793
|
renderSessionList();
|
|
787
794
|
ws.onmessage = origHandler;
|
|
795
|
+
// Flush buffered messages sent while session was pending
|
|
796
|
+
for (const pending of _pendingMsgs) {
|
|
797
|
+
send({ type: 'session-message', sessionId: realId, content: pending });
|
|
798
|
+
}
|
|
799
|
+
_pendingMsgs = [];
|
|
788
800
|
return;
|
|
789
801
|
}
|
|
790
802
|
// Pass through all other messages
|
|
@@ -888,7 +900,7 @@ function buildHtml({
|
|
|
888
900
|
el.className = 'message user';
|
|
889
901
|
el.innerHTML =
|
|
890
902
|
'<div class="msg-avatar">U</div>' +
|
|
891
|
-
'<div class="msg-bubble">' + esc(text).
|
|
903
|
+
'<div class="msg-bubble">' + esc(text).split('\\n').join('<br>') + '</div>';
|
|
892
904
|
messages.appendChild(el);
|
|
893
905
|
scrollToBottom();
|
|
894
906
|
}
|
|
@@ -978,6 +990,13 @@ function buildHtml({
|
|
|
978
990
|
showMessagesArea();
|
|
979
991
|
showTyping();
|
|
980
992
|
|
|
993
|
+
// If session is still pending (not yet confirmed by server), buffer
|
|
994
|
+
if (currentSessionId && currentSessionId.startsWith('pending-')) {
|
|
995
|
+
_pendingMsgs.push(text);
|
|
996
|
+
setTimeout(() => { btnSend.disabled = false; }, 500);
|
|
997
|
+
return;
|
|
998
|
+
}
|
|
999
|
+
|
|
981
1000
|
send({
|
|
982
1001
|
type: 'session-message',
|
|
983
1002
|
sessionId: currentSessionId,
|
|
@@ -1077,11 +1096,14 @@ function buildHtml({
|
|
|
1077
1096
|
if (window.marked) {
|
|
1078
1097
|
try { return marked.parse(text); } catch (_) { /* fall through */ }
|
|
1079
1098
|
}
|
|
1080
|
-
return esc(text).
|
|
1099
|
+
return esc(text).split('\\n').join('<br>');
|
|
1081
1100
|
}
|
|
1082
1101
|
|
|
1083
1102
|
// ── Start ────────────────────────────────────────────────────────────────
|
|
1103
|
+
// Connect immediately — do NOT wait for defer scripts (marked/hljs)
|
|
1084
1104
|
connect();
|
|
1105
|
+
// Init marked after defer scripts finish loading
|
|
1106
|
+
window.addEventListener('load', initMarked);
|
|
1085
1107
|
})();
|
|
1086
1108
|
</script>
|
|
1087
1109
|
</body>
|
|
@@ -84,10 +84,15 @@ export class WSSessionManager {
|
|
|
84
84
|
const sessionId = this._generateId();
|
|
85
85
|
const type = options.type || "agent";
|
|
86
86
|
const projectRoot = options.projectRoot || this.defaultProjectRoot;
|
|
87
|
-
const
|
|
87
|
+
const cfgLlm = this.config?.llm || {};
|
|
88
|
+
const provider = options.provider || cfgLlm.provider || "ollama";
|
|
88
89
|
const model =
|
|
89
|
-
options.model ||
|
|
90
|
-
|
|
90
|
+
options.model ||
|
|
91
|
+
cfgLlm.model ||
|
|
92
|
+
(provider === "ollama" ? "qwen2.5:7b" : null);
|
|
93
|
+
const baseUrl =
|
|
94
|
+
options.baseUrl || cfgLlm.baseUrl || "http://localhost:11434";
|
|
95
|
+
const apiKey = options.apiKey || cfgLlm.apiKey || null;
|
|
91
96
|
|
|
92
97
|
// Project context (rules.md, persona) is now loaded by buildSystemPrompt()
|
|
93
98
|
|
|
@@ -144,7 +149,7 @@ export class WSSessionManager {
|
|
|
144
149
|
messages,
|
|
145
150
|
provider,
|
|
146
151
|
model,
|
|
147
|
-
apiKey
|
|
152
|
+
apiKey,
|
|
148
153
|
baseUrl,
|
|
149
154
|
projectRoot,
|
|
150
155
|
rulesContent: null,
|