chainlesschain 0.45.0 → 0.45.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chainlesschain",
3
- "version": "0.45.0",
3
+ "version": "0.45.1",
4
4
  "description": "CLI for ChainlessChain - install, configure, and manage your personal AI management system",
5
5
  "type": "module",
6
6
  "bin": {
@@ -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.1</span>
463
+ <span id="version-label">v5.0.2.3</span>
464
464
  </div>
465
465
  </nav>
466
466
 
@@ -522,6 +522,7 @@ function buildHtml({
522
522
  let streamBuffer = '';
523
523
  let selectedSessionType = 'agent';
524
524
  let pendingQuestionResolve = null;
525
+ let _msgId = 0;
525
526
  const sessions = new Map(); // id → { id, title, type, createdAt }
526
527
 
527
528
  // ── DOM refs ─────────────────────────────────────────────────────────────
@@ -611,6 +612,7 @@ function buildHtml({
611
612
 
612
613
  function send(obj) {
613
614
  if (ws && ws.readyState === WebSocket.OPEN) {
615
+ if (!obj.id) { obj = Object.assign({ id: 'ui-' + (++_msgId) }, obj); }
614
616
  ws.send(JSON.stringify(obj));
615
617
  }
616
618
  }
@@ -625,34 +627,35 @@ function buildHtml({
625
627
 
626
628
  function handleMessage(msg) {
627
629
  switch (msg.type) {
628
- case 'auth-ok':
629
- onAuthenticated();
630
- break;
631
-
632
- case 'auth-error':
633
- setConnStatus('error');
634
- addSystemMsg('认证失败:' + (msg.error || '无效的 token'));
630
+ case 'auth-result':
631
+ if (msg.success) {
632
+ onAuthenticated();
633
+ } else {
634
+ setConnStatus('error');
635
+ addSystemMsg('认证失败:' + (msg.message || '无效的 token'));
636
+ }
635
637
  break;
636
638
 
637
639
  case 'pong':
638
640
  break;
639
641
 
640
642
  case 'session-created':
641
- if (msg.session) {
642
- sessions.set(msg.session.id, {
643
- id: msg.session.id,
644
- title: msg.session.title || '新会话',
645
- type: msg.session.type || 'agent',
646
- createdAt: msg.session.createdAt || Date.now(),
643
+ // Server sends { sessionId, sessionType }
644
+ if (msg.sessionId) {
645
+ sessions.set(msg.sessionId, {
646
+ id: msg.sessionId,
647
+ title: (msg.sessionType || 'agent') === 'agent' ? 'Agent 会话' : 'Chat 会话',
648
+ type: msg.sessionType || 'agent',
649
+ createdAt: Date.now(),
647
650
  });
648
651
  renderSessionList();
649
- if (currentSessionId === msg.session.id) {
652
+ if (currentSessionId === msg.sessionId) {
650
653
  updateChatHeader();
651
654
  }
652
655
  }
653
656
  break;
654
657
 
655
- case 'session-list':
658
+ case 'session-list-result':
656
659
  if (Array.isArray(msg.sessions)) {
657
660
  msg.sessions.forEach(s => {
658
661
  sessions.set(s.id, {
@@ -666,37 +669,56 @@ function buildHtml({
666
669
  }
667
670
  break;
668
671
 
669
- case 'session-message':
670
- // Non-streaming response
671
- if (msg.sessionId === currentSessionId && msg.content) {
672
- hideTyping();
673
- appendAiMsg(msg.content);
672
+ // Streaming: chat handler emits response-token per token
673
+ case 'response-token':
674
+ if (msg.sessionId === currentSessionId) {
675
+ if (!streamingMsgId) {
676
+ hideTyping();
677
+ streamBuffer = '';
678
+ streamingMsgId = 'stream-' + Date.now();
679
+ appendAiMsgStreaming(streamingMsgId);
680
+ }
681
+ streamBuffer += (msg.token || '');
682
+ updateStreamingMsg(streamingMsgId, streamBuffer);
683
+ }
684
+ break;
685
+
686
+ // Final response: both agent and chat handlers emit response-complete
687
+ case 'response-complete':
688
+ if (msg.sessionId === currentSessionId) {
689
+ if (streamingMsgId) {
690
+ finalizeStreamingMsg(streamingMsgId, streamBuffer || msg.content || '');
691
+ streamingMsgId = null;
692
+ streamBuffer = '';
693
+ } else {
694
+ // Agent mode: no token stream, show full response at once
695
+ hideTyping();
696
+ if (msg.content) appendAiMsg(msg.content);
697
+ }
698
+ maybeUpdateSessionTitle(currentSessionId);
674
699
  }
675
700
  break;
676
701
 
677
- case 'stream-start':
702
+ // Agent tool events — show as system info
703
+ case 'tool-executing':
678
704
  if (msg.sessionId === currentSessionId) {
679
- hideTyping();
680
- streamBuffer = '';
681
- streamingMsgId = 'stream-' + Date.now();
682
- appendAiMsgStreaming(streamingMsgId);
705
+ addSystemMsg('🔧 ' + (msg.display || msg.tool || '工具调用中...'));
683
706
  }
684
707
  break;
685
708
 
686
- case 'stream-data':
687
- if (msg.sessionId === currentSessionId && streamingMsgId) {
688
- streamBuffer += (msg.data || '');
689
- updateStreamingMsg(streamingMsgId, streamBuffer);
709
+ case 'tool-result':
710
+ // Silently consumed agent will emit response-complete after
711
+ break;
712
+
713
+ case 'model-switch':
714
+ if (msg.sessionId === currentSessionId) {
715
+ addSystemMsg('🔄 模型切换: ' + msg.from + ' → ' + msg.to + ' (' + msg.reason + ')');
690
716
  }
691
717
  break;
692
718
 
693
- case 'stream-end':
719
+ case 'command-response':
694
720
  if (msg.sessionId === currentSessionId) {
695
- finalizeStreamingMsg(streamingMsgId, streamBuffer);
696
- streamingMsgId = null;
697
- streamBuffer = '';
698
- // Update session title from first user message
699
- maybeUpdateSessionTitle(currentSessionId);
721
+ addSystemMsg('✅ ' + JSON.stringify(msg.result || {}));
700
722
  }
701
723
  break;
702
724
 
@@ -747,15 +769,15 @@ function buildHtml({
747
769
  ws.onmessage = ev => {
748
770
  let msg;
749
771
  try { msg = JSON.parse(ev.data); } catch { return; }
750
- if (msg.type === 'session-created' && msg.session) {
772
+ if (msg.type === 'session-created' && msg.sessionId) {
751
773
  // Replace temp id
752
774
  sessions.delete(tempId);
753
- const realId = msg.session.id;
775
+ const realId = msg.sessionId;
754
776
  sessions.set(realId, {
755
777
  id: realId,
756
- title: msg.session.title || (selectedSessionType === 'agent' ? 'Agent 会话' : 'Chat 会话'),
757
- type: msg.session.type || selectedSessionType,
758
- createdAt: msg.session.createdAt || Date.now(),
778
+ title: selectedSessionType === 'agent' ? 'Agent 会话' : 'Chat 会话',
779
+ type: msg.sessionType || selectedSessionType,
780
+ createdAt: Date.now(),
759
781
  });
760
782
  if (currentSessionId === tempId) {
761
783
  currentSessionId = realId;