-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathopencode-client.html
More file actions
105 lines (95 loc) · 6.86 KB
/
opencode-client.html
File metadata and controls
105 lines (95 loc) · 6.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>天翼云电脑AI CoSpace</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #1a1a2e; color: #eee; }
.container { max-width: 900px; margin: 0 auto; padding: 20px; min-height: 100vh; }
header { text-align: center; padding: 15px 0; border-bottom: 1px solid #333; margin-bottom: 15px; }
h1 { font-size: 1.5rem; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.status { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 8px; font-size: 0.85rem; }
.status-dot { width: 8px; height: 8px; border-radius: 50%; background: #666; }
.status-dot.online { background: #4ade80; box-shadow: 0 0 10px #4ade80; }
.chat-container { background: #16162a; border-radius: 12px; padding: 15px; margin-bottom: 15px; min-height: 400px; max-height: 60vh; overflow-y: auto; }
.message { margin-bottom: 12px; padding: 12px; border-radius: 10px; max-width: 85%; }
.message.user { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); margin-left: auto; }
.message.assistant { background: #2a2a4a; margin-right: auto; }
.message.system { background: transparent; margin: 10px auto; text-align: center; font-size: 0.85rem; color: #888; }
.message.error { background: #3a1a1a; border: 1px solid #ef4444; margin: 10px auto; }
.message-header { display: flex; justify-content: space-between; margin-bottom: 6px; font-size: 0.75rem; opacity: 0.7; }
.message-content { white-space: pre-wrap; line-height: 1.5; font-size: 0.95rem; }
.input-area { display: flex; gap: 10px; background: #16162a; padding: 12px; border-radius: 12px; }
textarea { flex: 1; background: #2a2a4a; border: 1px solid #444; border-radius: 8px; color: #eee; padding: 10px; resize: none; height: 50px; font-family: inherit; }
textarea:focus { outline: none; border-color: #667eea; }
button { padding: 0 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border: none; border-radius: 8px; color: white; font-weight: 600; cursor: pointer; }
button:hover:not(:disabled) { transform: scale(1.02); }
button:disabled { opacity: 0.5; cursor: not-allowed; }
.loading { display: inline-block; width: 14px; height: 14px; border: 2px solid #fff; border-top-color: transparent; border-radius: 50%; animation: spin 0.8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.settings-bar { display: flex; gap: 10px; align-items: center; background: #16162a; padding: 10px 15px; border-radius: 10px; margin-bottom: 15px; }
.settings-bar label { font-size: 0.8rem; color: #888; }
.settings-bar select { background: #2a2a4a; border: 1px solid #444; border-radius: 6px; color: #eee; padding: 6px 10px; }
/* Processing indicator */
.processing-indicator { background: #1a1a3e; border-radius: 10px; padding: 12px; margin-bottom: 12px; border-left: 3px solid #667eea; }
.processing-header { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; font-size: 0.8rem; color: #888; }
.processing-spinner { width: 12px; height: 12px; border: 2px solid #667eea; border-top-color: transparent; border-radius: 50%; animation: spin 0.8s linear infinite; }
.processing-steps { font-size: 0.85rem; }
.processing-step { display: flex; align-items: flex-start; gap: 8px; margin-bottom: 6px; opacity: 0.7; }
.processing-step.active { opacity: 1; color: #4ade80; }
.processing-step.completed { opacity: 0.5; text-decoration: line-through; }
.step-icon { flex-shrink: 0; margin-top: 2px; }
.step-text { flex: 1; }
.step-detail { font-size: 0.75rem; color: #666; margin-top: 2px; }
/* Reasoning block */
.reasoning-block { background: #1a1a2e; border-radius: 8px; padding: 10px; margin: 8px 0; font-size: 0.85rem; border-left: 2px solid #667eea; }
.reasoning-header { display: flex; align-items: center; gap: 6px; color: #888; font-size: 0.75rem; margin-bottom: 6px; cursor: pointer; }
.reasoning-content { color: #aaa; line-height: 1.4; max-height: 200px; overflow-y: auto; }
.reasoning-content.collapsed { display: none; }
/* Tool call */
.tool-call { background: #1a2a1a; border-radius: 8px; padding: 10px; margin: 8px 0; border-left: 2px solid #4ade80; }
.tool-header { display: flex; align-items: center; gap: 6px; font-size: 0.8rem; color: #4ade80; margin-bottom: 4px; }
.tool-name { font-family: monospace; background: #2a3a2a; padding: 2px 6px; border-radius: 4px; }
.tool-result { font-size: 0.85rem; color: #ccc; max-height: 150px; overflow-y: auto; margin-top: 6px; }
/* Stream text */
.stream-text { animation: fadeIn 0.3s ease-in; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
/* AI text content */
.ai-text-content { line-height: 1.5; }
/* Pre tag styling */
pre { background: #0a0a1a; padding: 8px; border-radius: 4px; overflow-x: auto; font-size: 0.8rem; margin: 4px 0; }
strong { color: #888; }
</style>
</head>
<body>
<div class="container">
<header>
<h1>天翼云电脑AI CoSpace</h1>
<div class="status">
<span class="status-dot" id="statusDot"></span>
<span id="statusText">初始化中...</span>
</div>
</header>
<div class="settings-bar">
<label>Server:</label>
<input type="text" id="serverUrl" value="http://localhost:4096" style="width: 150px; background: #2a2a4a; border: 1px solid #444; border-radius: 6px; color: #eee; padding: 6px 10px;">
<button id="connectBtn" style="padding: 6px 16px;">连接</button>
<span style="flex:1;"></span>
<label>模型:</label>
<select id="modelSelect" style="width: 200px;"></select>
<button id="newSessionBtn" style="padding: 6px 16px; background: #444;">新建会话</button>
</div>
<div class="chat-container" id="chatContainer">
<div class="message system">点击"连接"按钮连接到 OpenCode 服务器</div>
</div>
<div class="input-area">
<textarea id="promptInput" placeholder="输入指令... (Enter 发送)" disabled></textarea>
<button id="sendBtn" disabled>发送</button>
<button id="stopBtn" disabled style="background: #ef4444; display: none;">停止</button>
</div>
</div>
<script type="module" src="js/main.js"></script>
</body>
</html>