diff --git a/src/views/contextCompress.ts b/src/views/contextCompress.ts
new file mode 100644
index 0000000..1e68b00
--- /dev/null
+++ b/src/views/contextCompress.ts
@@ -0,0 +1,249 @@
+/**
+ * 上下文压缩组件
+ * 提供上下文使用情况显示和压缩功能
+ */
+
+/**
+ * 获取上下文压缩组件的 HTML 内容
+ */
+export function getContextCompressContent(): string {
+ return `
+
+
+
+
+
+
+
0%
+
+
+
+
+
+
+ 0k / 200k 已用上下文
+
+
+
+
+
+ `;
+}
+
+/**
+ * 获取上下文压缩组件的样式
+ */
+export function getContextCompressStyles(): string {
+ return `
+ /* 上下文显示样式 */
+ .context-display {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ position: relative;
+ }
+ .context-info {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ height: 40px;
+ background: transparent;
+ border: none;
+ border-radius: 4px;
+ font-size: 14px;
+ font-weight: 500;
+ color: var(--vscode-foreground);
+ transition: opacity 0.3s ease;
+ box-shadow: none;
+ position: relative;
+ overflow: hidden;
+ cursor: pointer;
+ }
+ .context-info:hover {
+ opacity: 0.8;
+ }
+ .database-icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 12px;
+ height: 12px;
+ position: relative;
+ }
+ .db-svg {
+ width: 100%;
+ height: 100%;
+ }
+ .db-body {
+ fill: #ffffff;
+ }
+ .db-fill {
+ fill: #409eff;
+ transition: all 0.3s ease;
+ }
+ .context-percentage {
+ font-size: 14px;
+ font-weight: 500;
+ color: var(--vscode-foreground);
+ text-align: right;
+ }
+ /* 上下文信息弹窗样式 */
+ .context-panel {
+ position: absolute;
+ bottom: 100%;
+ left: 50%;
+ transform: translateX(-50%);
+ margin-bottom: 8px;
+ z-index: 1000;
+ animation: fadeInUp 0.2s ease-out;
+ display: none;
+ }
+ .context-panel.active {
+ display: block;
+ }
+ .context-panel::after {
+ content: "";
+ position: absolute;
+ bottom: -6px;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 0;
+ height: 0;
+ border-left: 6px solid transparent;
+ border-right: 6px solid transparent;
+ border-top: 6px solid #ffffff;
+ }
+ .context-panel-content {
+ background: #ffffff;
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ border-radius: 8px;
+ padding: 12px;
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
+ backdrop-filter: blur(10px);
+ min-width: 160px;
+ }
+ .context-info-text {
+ font-size: 12px;
+ color: #374151;
+ text-align: center;
+ margin-bottom: 8px;
+ white-space: nowrap;
+ }
+ .compress-button {
+ width: 100%;
+ background: linear-gradient(145deg, #3b82f6 0%, #1d4ed8 100%);
+ border: 1px solid rgba(59, 130, 246, 0.3);
+ border-radius: 6px;
+ color: white;
+ font-size: 12px;
+ font-weight: 500;
+ padding: 6px 12px;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ }
+ .compress-button:hover {
+ background: linear-gradient(145deg, #2563eb 0%, #1e40af 100%);
+ transform: translateY(-1px);
+ box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3);
+ }
+ .compress-button:active {
+ transform: translateY(0);
+ }
+ @keyframes fadeInUp {
+ from {
+ opacity: 0;
+ transform: translateX(-50%) translateY(10px);
+ }
+ to {
+ opacity: 1;
+ transform: translateX(-50%) translateY(0);
+ }
+ }
+ `;
+}
+
+/**
+ * 获取上下文压缩组件的脚本
+ */
+export function getContextCompressScript(): string {
+ return `
+ // 上下文面板相关函数
+ function toggleContextPanel() {
+ const contextPanel = document.getElementById('contextPanel');
+ if (contextPanel) {
+ if (contextPanel.classList.contains('active')) {
+ contextPanel.classList.remove('active');
+ } else {
+ contextPanel.classList.add('active');
+ }
+ }
+ }
+
+ function compressConversation() {
+ // 发送压缩会话请求
+ vscode.postMessage({ command: 'compressConversation' });
+ addMessage('正在压缩会话...', 'bot');
+
+ // 关闭面板
+ const contextPanel = document.getElementById('contextPanel');
+ if (contextPanel) {
+ contextPanel.classList.remove('active');
+ }
+ }
+
+ function updateContextDisplay(currentTokens, maxTokens) {
+ const percentage = Math.min(Math.round((currentTokens / maxTokens) * 100), 100);
+
+ // 更新百分比显示
+ const contextPercentage = document.getElementById('contextPercentage');
+ if (contextPercentage) {
+ contextPercentage.textContent = percentage + '%';
+ }
+
+ // 更新详细信息
+ const contextInfoText = document.getElementById('contextInfoText');
+ if (contextInfoText) {
+ const currentK = Math.round((currentTokens / 1000) * 10) / 10;
+ const maxK = Math.round(maxTokens / 1000);
+ contextInfoText.textContent = \`\${currentK}k / \${maxK}k 已用上下文\`;
+ }
+
+ // 更新SVG填充效果(从下往上填充)
+ const fillRect = document.getElementById('fillRect');
+ if (fillRect) {
+ const fillHeight = (1024 * percentage) / 100;
+ const fillY = 1024 - fillHeight;
+ fillRect.setAttribute('y', fillY.toString());
+ fillRect.setAttribute('height', fillHeight.toString());
+ }
+ }
+
+ // 点击外部关闭上下文面板
+ document.addEventListener('click', (event) => {
+ const contextDisplay = document.querySelector('.context-display');
+ const contextPanel = document.getElementById('contextPanel');
+
+ if (contextPanel && contextPanel.classList.contains('active') && contextDisplay) {
+ if (!contextDisplay.contains(event.target)) {
+ contextPanel.classList.remove('active');
+ }
+ }
+ });
+ `;
+}
diff --git a/src/views/inputArea.ts b/src/views/inputArea.ts
index 8c9ba5c..f7646e3 100644
--- a/src/views/inputArea.ts
+++ b/src/views/inputArea.ts
@@ -9,6 +9,11 @@ import {
getContextButtonStyles,
getContextButtonScript
} from "./contextButton";
+import {
+ getContextCompressContent,
+ getContextCompressStyles,
+ getContextCompressScript
+} from "./contextCompress";
/**
* 获取输入区域的 HTML 内容
@@ -60,41 +65,7 @@ export function getInputAreaContent(): string {
${getModelSelectorContent()}