feat: 优化控制台交互 - 移除冗余选项、添加自动执行和任务详情功能
This commit is contained in:
47
console.html
47
console.html
@@ -91,13 +91,17 @@
|
|||||||
<select id="taskType">
|
<select id="taskType">
|
||||||
<option value="ephemeral">即时任务 (Ephemeral)</option>
|
<option value="ephemeral">即时任务 (Ephemeral)</option>
|
||||||
<option value="persistent">持久任务 (Persistent)</option>
|
<option value="persistent">持久任务 (Persistent)</option>
|
||||||
<option value="scheduled">定时任务 (Scheduled)</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>任务描述 (Prompt)</label>
|
<label>任务描述 (Prompt)</label>
|
||||||
<textarea id="taskPrompt" placeholder="输入任务描述..."></textarea>
|
<textarea id="taskPrompt" placeholder="输入任务描述..."></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" id="autoExecute" checked> 创建后自动执行
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<button class="btn" onclick="createTask()">创建任务</button>
|
<button class="btn" onclick="createTask()">创建任务</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
@@ -121,6 +125,10 @@
|
|||||||
<tbody id="tasksTable"></tbody>
|
<tbody id="tasksTable"></tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card" id="taskDetailPanel" style="display: none;">
|
||||||
|
<h2>任务详情</h2>
|
||||||
|
<div id="taskDetailContent"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 定时任务 -->
|
<!-- 定时任务 -->
|
||||||
@@ -161,6 +169,7 @@
|
|||||||
<th>ID</th>
|
<th>ID</th>
|
||||||
<th>名称</th>
|
<th>名称</th>
|
||||||
<th>Cron</th>
|
<th>Cron</th>
|
||||||
|
<th>状态</th>
|
||||||
<th>提示词</th>
|
<th>提示词</th>
|
||||||
<th>操作</th>
|
<th>操作</th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -322,6 +331,7 @@
|
|||||||
async function createTask() {
|
async function createTask() {
|
||||||
const type = document.getElementById('taskType').value;
|
const type = document.getElementById('taskType').value;
|
||||||
const prompt = document.getElementById('taskPrompt').value;
|
const prompt = document.getElementById('taskPrompt').value;
|
||||||
|
const autoExecute = document.getElementById('autoExecute').checked;
|
||||||
if (!prompt) return alert('请输入任务描述');
|
if (!prompt) return alert('请输入任务描述');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -334,6 +344,11 @@
|
|||||||
addLog('创建任务: ' + task.id, 'info');
|
addLog('创建任务: ' + task.id, 'info');
|
||||||
document.getElementById('taskPrompt').value = '';
|
document.getElementById('taskPrompt').value = '';
|
||||||
loadTasks();
|
loadTasks();
|
||||||
|
|
||||||
|
if (autoExecute) {
|
||||||
|
addLog('正在自动执行任务...', 'info');
|
||||||
|
await executeTask(task.id, type === 'persistent');
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
alert('创建失败: ' + e.message);
|
alert('创建失败: ' + e.message);
|
||||||
}
|
}
|
||||||
@@ -351,6 +366,7 @@
|
|||||||
<td>${t.prompt.substring(0, 30)}${t.prompt.length > 30 ? '...' : ''}</td>
|
<td>${t.prompt.substring(0, 30)}${t.prompt.length > 30 ? '...' : ''}</td>
|
||||||
<td><span class="status-badge status-${t.status}">${t.status}</span></td>
|
<td><span class="status-badge status-${t.status}">${t.status}</span></td>
|
||||||
<td class="flex">
|
<td class="flex">
|
||||||
|
<button class="btn" style="padding: 5px 10px; font-size: 12px;" onclick="viewTask('${t.id}')">详情</button>
|
||||||
<button class="btn" style="padding: 5px 10px; font-size: 12px;" onclick="executeTask('${t.id}', false)">执行</button>
|
<button class="btn" style="padding: 5px 10px; font-size: 12px;" onclick="executeTask('${t.id}', false)">执行</button>
|
||||||
<button class="btn btn-success" style="padding: 5px 10px; font-size: 12px;" onclick="executeTask('${t.id}', true)">异步</button>
|
<button class="btn btn-success" style="padding: 5px 10px; font-size: 12px;" onclick="executeTask('${t.id}', true)">异步</button>
|
||||||
<button class="btn btn-danger" style="padding: 5px 10px; font-size: 12px;" onclick="abortTask('${t.id}')">中止</button>
|
<button class="btn btn-danger" style="padding: 5px 10px; font-size: 12px;" onclick="abortTask('${t.id}')">中止</button>
|
||||||
@@ -362,6 +378,32 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function viewTask(taskId) {
|
||||||
|
try {
|
||||||
|
const res = await fetch(API_BASE + '/task/' + taskId);
|
||||||
|
const task = await res.json();
|
||||||
|
const panel = document.getElementById('taskDetailPanel');
|
||||||
|
const content = document.getElementById('taskDetailContent');
|
||||||
|
panel.style.display = 'block';
|
||||||
|
content.innerHTML = `
|
||||||
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px;">
|
||||||
|
<div><strong>任务ID:</strong> ${task.id}</div>
|
||||||
|
<div><strong>类型:</strong> ${task.type}</div>
|
||||||
|
<div><strong>状态:</strong> <span class="status-badge status-${task.status}">${task.status}</span></div>
|
||||||
|
<div><strong>Session ID:</strong> ${task.session_id || '-'}</div>
|
||||||
|
<div style="grid-column: 1 / -1;"><strong>提示词:</strong> <pre style="background: #0f0f23; padding: 10px; border-radius: 4px; margin-top: 5px;">${task.prompt}</pre></div>
|
||||||
|
${task.error ? `<div style="grid-column: 1 / -1; color: #ff4757;"><strong>错误信息:</strong> ${task.error}</div>` : ''}
|
||||||
|
<div><strong>创建时间:</strong> ${task.created_at || '-'}</div>
|
||||||
|
<div><strong>开始时间:</strong> ${task.started_at || '-'}</div>
|
||||||
|
<div><strong>完成时间:</strong> ${task.finished_at || '-'}</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
panel.scrollIntoView({behavior: 'smooth'});
|
||||||
|
} catch (e) {
|
||||||
|
alert('获取详情失败: ' + e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function executeTask(taskId, async_) {
|
async function executeTask(taskId, async_) {
|
||||||
try {
|
try {
|
||||||
const endpoint = async_ ? '/execute_async' : '/execute';
|
const endpoint = async_ ? '/execute_async' : '/execute';
|
||||||
@@ -418,7 +460,8 @@
|
|||||||
<td>${s.id}</td>
|
<td>${s.id}</td>
|
||||||
<td>${s.name || '-'}</td>
|
<td>${s.name || '-'}</td>
|
||||||
<td>${s.cron}</td>
|
<td>${s.cron}</td>
|
||||||
<td>${(s.prompt || '').substring(0, 30)}...</td>
|
<td><span class="status-badge status-${s.enabled ? 'completed' : 'pending'}">${s.enabled ? '已启用' : '已禁用'}</span></td>
|
||||||
|
<td>${(s.prompt || '').substring(0, 30)}${(s.prompt || '').length > 30 ? '...' : ''}</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn btn-danger" style="padding: 5px 10px; font-size: 12px;" onclick="deleteSchedule('${s.id}')">删除</button>
|
<button class="btn btn-danger" style="padding: 5px 10px; font-size: 12px;" onclick="deleteSchedule('${s.id}')">删除</button>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ http://localhost:8888/console.html
|
|||||||
|
|
||||||
| Tab | 功能 |
|
| Tab | 功能 |
|
||||||
|-----|------|
|
|-----|------|
|
||||||
| 任务管理 | 创建、执行、管理即时/持久/定时任务 |
|
| 任务管理 | 创建、执行一次性任务 |
|
||||||
| 定时任务 | 创建和管理 Cron 定时任务 |
|
| 定时任务 | 创建和管理 Cron 循环调度任务 |
|
||||||
| 历史记录 | 查看任务执行历史 |
|
| 历史记录 | 查看任务执行历史 |
|
||||||
| 持久会话 | 创建和管理多轮对话会话 |
|
| 持久会话 | 创建和管理多轮对话会话 |
|
||||||
| 实时日志 | WebSocket 实时推送的任务状态 |
|
| 实时日志 | WebSocket 实时推送的任务状态 |
|
||||||
@@ -22,39 +22,61 @@ http://localhost:8888/console.html
|
|||||||
|
|
||||||
## 1. 任务管理
|
## 1. 任务管理
|
||||||
|
|
||||||
|
> 用于创建一次性执行的任务。任务创建后不会自动执行,需要手动点击「执行」按钮。
|
||||||
|
|
||||||
|
### 任务类型
|
||||||
|
|
||||||
|
| 类型 | 说明 | 使用场景 |
|
||||||
|
|------|------|----------|
|
||||||
|
| **Ephemeral (即时任务)** | 一次性任务,执行完成后结束 | 临时性的 AI 问答、代码生成等 |
|
||||||
|
| **Persistent (持久任务)** | 可多轮交互的任务会话 | 需要多轮对话才能完成的任务 |
|
||||||
|
|
||||||
### 创建任务
|
### 创建任务
|
||||||
|
|
||||||
1. 选择任务类型:
|
1. 选择任务类型(即时任务/持久任务)
|
||||||
- **Ephemeral (即时任务)**:一次性任务,执行后结束
|
|
||||||
- **Persistent (持久任务)**:可多轮交互的任务
|
|
||||||
- **Scheduled (定时任务)**:需要配合定时任务模块使用
|
|
||||||
|
|
||||||
2. 输入任务描述 (Prompt)
|
2. 输入任务描述 (Prompt)
|
||||||
|
3. 可选:勾选「创建后自动执行」
|
||||||
|
4. 点击「创建任务」
|
||||||
|
|
||||||
3. 点击「创建任务」
|
> 💡 **提示**:默认勾选「创建后自动执行」,任务创建后会立即执行。如果需要手动控制执行,取消勾选即可。
|
||||||
|
|
||||||
### 执行任务
|
### 执行任务
|
||||||
|
|
||||||
创建任务后,在任务列表中可以:
|
创建任务后,在任务列表中可以执行以下操作:
|
||||||
|
|
||||||
| 按钮 | 功能 |
|
| 按钮 | 功能 |
|
||||||
|------|------|
|
|------|------|
|
||||||
|
| 详情 | 查看任务的完整信息,包括 Session ID、错误信息等 |
|
||||||
| 执行 | 同步执行任务,等待完成 |
|
| 执行 | 同步执行任务,等待完成 |
|
||||||
| 异步 | 异步执行任务,立即返回 |
|
| 异步 | 异步执行任务,立即返回 |
|
||||||
| 中止 | 终止正在执行的任务 |
|
| 中止 | 终止正在执行的任务 |
|
||||||
|
|
||||||
### 任务状态
|
### 任务详情
|
||||||
|
|
||||||
- `pending` - 待执行
|
点击「详情」按钮可以查看任务的完整信息:
|
||||||
- `running` - 执行中
|
|
||||||
- `completed` - 已完成
|
- **任务ID**:任务的唯一标识
|
||||||
- `failed` - 执行失败
|
- **类型**:即时任务/持久任务
|
||||||
- `aborted` - 已中止
|
- **状态**:任务的当前状态
|
||||||
|
- **Session ID**:OpenCode 会话 ID,可用于在 OpenCode 界面查看对话详情
|
||||||
|
- **提示词**:任务的完整描述
|
||||||
|
- **错误信息**:任务失败时的错误原因
|
||||||
|
- **创建/开始/完成时间**:任务的时间线
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. 定时任务
|
## 2. 定时任务
|
||||||
|
|
||||||
|
> 用于创建**循环执行**的定时调度任务。基于 Cron 表达式,在指定时间自动执行任务。
|
||||||
|
|
||||||
|
### 与「任务管理」的区别
|
||||||
|
|
||||||
|
| 功能 | 任务管理 | 定时任务 |
|
||||||
|
|------|----------|----------|
|
||||||
|
| 执行方式 | 手动点击执行 | 自动执行 |
|
||||||
|
| 执行次数 | 一次 | 循环执行 |
|
||||||
|
| 配置方式 | 创建后手动执行 | 配置 Cron 表达式,自动触发 |
|
||||||
|
|
||||||
### 创建定时任务
|
### 创建定时任务
|
||||||
|
|
||||||
| 字段 | 说明 |
|
| 字段 | 说明 |
|
||||||
@@ -63,7 +85,19 @@ http://localhost:8888/console.html
|
|||||||
| 任务名称 | 显示名称,如「每日任务」 |
|
| 任务名称 | 显示名称,如「每日任务」 |
|
||||||
| Cron 表达式 | 执行时间,如 `0 9 * * *` (每天9点) |
|
| Cron 表达式 | 执行时间,如 `0 9 * * *` (每天9点) |
|
||||||
| 执行内容 | 定时执行的 Prompt |
|
| 执行内容 | 定时执行的 Prompt |
|
||||||
| 启用 | 是否启用此定时任务 |
|
| 启用 | 是否启用此定时任务(未启用则不会执行) |
|
||||||
|
|
||||||
|
### 定时任务列表
|
||||||
|
|
||||||
|
表格显示所有定时任务,包含以下信息:
|
||||||
|
|
||||||
|
| 列 | 说明 |
|
||||||
|
|-----|------|
|
||||||
|
| ID | 任务唯一标识 |
|
||||||
|
| 名称 | 任务显示名称 |
|
||||||
|
| Cron | 执行时间表达式 |
|
||||||
|
| 状态 | 已启用 / 已禁用 |
|
||||||
|
| 提示词 | 执行内容摘要 |
|
||||||
|
|
||||||
### 常用 Cron 示例
|
### 常用 Cron 示例
|
||||||
|
|
||||||
@@ -78,43 +112,77 @@ http://localhost:8888/console.html
|
|||||||
|
|
||||||
## 3. 历史记录
|
## 3. 历史记录
|
||||||
|
|
||||||
- 查看所有已完成的任务记录
|
> 查看所有已完成的任务执行历史记录。
|
||||||
- 支持限制显示条数
|
|
||||||
- 可清空历史记录
|
### 功能说明
|
||||||
|
|
||||||
|
- **查看历史**:显示所有任务的执行记录,包括类型、描述、状态、时间等
|
||||||
|
- **显示条数**:可自定义显示的记录数量
|
||||||
|
- **清空历史**:一键清空所有历史记录
|
||||||
|
|
||||||
|
### 任务状态说明
|
||||||
|
|
||||||
|
| 状态 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `pending` | 待执行 |
|
||||||
|
| `running` | 执行中 |
|
||||||
|
| `completed` | 已完成 |
|
||||||
|
| `failed` | 执行失败 |
|
||||||
|
| `aborted` | 已中止 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 4. 持久会话
|
## 4. 持久会话
|
||||||
|
|
||||||
### 创建会话
|
> 创建可**多轮交互**的对话会话。与「任务管理」中的即时任务不同,持久会话可以多次发送消息,保持上下文连贯。
|
||||||
|
|
||||||
输入会话名称(可选),点击「创建」
|
### 与即时任务的区别
|
||||||
|
|
||||||
### 发送消息
|
| 特性 | 即时任务 | 持久会话 |
|
||||||
|
|------|----------|----------|
|
||||||
|
| 交互次数 | 单次 | 多次 |
|
||||||
|
| 上下文 | 不保持 | 自动保持 |
|
||||||
|
| 适用场景 | 简单问答 | 复杂任务、多轮对话 |
|
||||||
|
|
||||||
1. 在列表中找到目标会话
|
### 使用流程
|
||||||
2. 点击「发消息」按钮
|
|
||||||
3. 输入消息内容
|
1. **创建会话**:输入会话名称(可选),点击「创建」
|
||||||
4. 选择发送方式:
|
2. **发送消息**:点击会话的「发消息」按钮
|
||||||
- **同步发送**:等待响应返回
|
3. **选择发送方式**:
|
||||||
|
- **同步发送**:等待 AI 响应返回后再操作
|
||||||
- **异步发送**:立即返回,任务在后台执行
|
- **异步发送**:立即返回,任务在后台执行
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5. 实时日志
|
## 5. 实时日志
|
||||||
|
|
||||||
通过 WebSocket 实时显示:
|
> 通过 WebSocket 实时显示任务状态和系统消息。
|
||||||
|
|
||||||
- 任务状态变化
|
### 显示内容
|
||||||
- WebSocket 连接状态
|
|
||||||
- 操作日志
|
- 任务创建、执行、完成的实时通知
|
||||||
|
- WebSocket 连接状态变化
|
||||||
|
- 操作日志和错误信息
|
||||||
|
|
||||||
|
### 连接状态
|
||||||
|
|
||||||
|
页面左上角显示 WebSocket 连接状态:
|
||||||
|
- **已连接** - 绿色圆点,正常接收消息
|
||||||
|
- **未连接** - 红色圆点,需要刷新页面重连
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 快捷操作
|
## 快速参考
|
||||||
|
|
||||||
- **自动刷新**:健康检查和任务列表每 5 秒自动刷新
|
### 功能对比
|
||||||
- **WebSocket**:页面左上角显示连接状态
|
|
||||||
|
| 需求 | 推荐功能 |
|
||||||
|
|------|----------|
|
||||||
|
| 临时性的 AI 问答 | 任务管理 → 即时任务 |
|
||||||
|
| 需要多轮对话的复杂任务 | 任务管理 → 持久任务 |
|
||||||
|
| 每天定时执行某任务 | 定时任务 |
|
||||||
|
| 查看任务执行历史 | 历史记录 |
|
||||||
|
| 实时监控任务状态 | 实时日志 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user