@tasklens/vue
v0.1.0
Published
TaskLens Vue 3 组件层:AgentTaskPanel / ApprovalGate / RunLog / RunReplay + useRun / useRunStream(零运行时依赖,不含 Vue)
Downloads
14
Maintainers
Readme
@tasklens/vue
TaskLens 的 Vue 3 组件层。 把 Agent 的每一步、每次工具调用、每次人工审批,变成用户看得懂的界面。
- Vue 原生优先:
<script setup lang="ts">写法,完整 props / slots / emits 类型推导 - 零运行时依赖(除
@tasklens/protocol);vue是 peerDependency,不会打进产物 - SSR 安全(Nuxt 3 可用),首屏可用
@tasklens/server的快照 - 主题走 CSS 变量,不强制 Tailwind
pnpm add @tasklens/vue @tasklens/protocol
# 想用 createRun() 埋点再加:pnpm add @tasklens/core// 样式只需引入一次
import '@tasklens/vue/style.css'三档接入(换档只换数据来源,不换界面)
档 1 · Agent 跑在浏览器里(零后端)
<script setup lang="ts">
import { createRun } from '@tasklens/core'
import { AgentTaskPanel } from '@tasklens/vue'
const run = createRun({ goal: '给 20 位未激活用户发激活邮件' })
// run.plan() / run.stepStart() / run.tool() / run.requestApproval() …
</script>
<template>
<AgentTaskPanel :run="run" />
</template>档 2 · Agent 跑在 Node 里,浏览器通过 SSE 观看
<AgentTaskPanel
:stream-url="`/api/tasklens/runs/${runId}/stream`"
:decide="submitDecision"
:retry-step="retryStep"
/>断线重连、Last-Event-ID 续传、按 id 去重、乱序纠正都在组件内部完成 —— 你只给一个 URL 和两个回调。
档 0 · 粘一份 JSON 就出面板(零后端、零 key、零规范)
<script setup lang="ts">
import { RunReplay } from '@tasklens/vue'
// 手写的、别人导出的、缺字段的 —— 直接丢进去就行
const events = [
{ type: 'run:start', goal: '整理本周销售线索' },
{ type: 'plan', steps: ['抓取线索', '去重打分', '生成报告'] },
{ type: 'step:start', stepId: 'step_1' },
{ type: 'tool:call', stepId: 'step_1', name: 'fetch_leads', args: { range: '7d' } },
{ type: 'tool:result', ok: true, result: { count: 128 }, ms: 1840 },
{ type: 'step:done', stepId: 'step_1' },
]
</script>
<template>
<RunReplay :events="events" auto-play :speed="2" />
</template>这是整个设计里最重要的一条产品判断:手里只有一段 Agent 日志的人, 应该立刻看到完整面板,而不是先被告知"请先读懂信封规范"。
RunReplay 的 events 故意声明为 unknown:档 0 的数据类型在编译期不可能准确。
内部走 toRunEvents() 补全信封与无歧义载荷
(tool_call → tool:call、steps 传字符串数组、tool:result 与最近的调用配对、
缺 id/seq/at 自动生成、缺 run:start 自动补一条……)。
但改了什么一定会告诉你 —— 面板上方会出现一条提示(下例是真实渲染结果):
! 已自动补全 6 行 [查看改动]
envelope-filled 6 处 第 1–6 行 id / runId / seq / at / schemaVersion / callId
plan-strings 1 处 第 2 行 steps
call-id-filled 1 处 第 4 行 callId
call-id-paired 1 处 第 5 行 callId列表按 code 归并(不是逐条展开):档 0 的常态是"每一行都要补信封", 逐条列会变成几千行噪音,归并后每个 code 只占一行。
静默补全是最危险的一种"好用":面板看着正常,用户就永远不知道自己的日志本来有问题。
不需要这个提示时,自己先调 toRunEvents() 把 events 传进来即可(已经是合法事件就不提示)。
修不好的行不会消失:它们被降级成"格式异常事件"折叠在时间线末尾, 原始 JSON 一眼可查 —— 不丢、不猜、不白屏。
组件
| 组件 | 作用 |
| --- | --- |
| AgentTaskPanel | 主面板:目标 + 状态 + 时间线 + 步骤 + 工具调用 + 底部统计 |
| ApprovalGate | 审批卡片:摘要 / 结构化预览 / 风险等级 / 批准 · 修改后批准 · 拒绝 |
| RunLog | 可折叠原始日志(入参、出参、耗时、token、错误原文) |
| RunReplay | 事件数组回放器(play / pause / restart / stepForward / seek,支持 v-model:progress) |
| 展示组件 | PanelHeader PanelFooter ApprovalBanner TaskTimeline StepItem ToolCallItem PreviewBlock JsonBlock StatusBadge RiskBadge EmptyState UnknownEventItem —— 都可单独使用 |
AgentTaskPanel 主要 props
| prop | 说明 |
| --- | --- |
| run / events / streamUrl | 三选一,对应上面三档 |
| decide / retryStep | 决策与重试回传通道;不传 = 只读 |
| readonly | 显式强制只读 |
| renderers | 自定义工具渲染器(按工具名注册) |
| title / locale / theme / colorScheme | 展示层 |
| collapsible / defaultCollapsed / showFooter | 形态 |
| virtualThreshold | 超过该条数启用虚拟滚动 |
| by | 决策人标识(随决策回传,用于审计) |
| streamOptions | SSE 调优(退避序列、注入 EventSource 工厂) |
Slots:header-actions / step-pending / footer-actions。
Emits:decide / retry-step / export / connection-change / update:collapsed。
Expose:state / events / focusApproval(id) / reconnect()。
id 在 Vue 3.4 + SSR 下建议显式传入(面板 DOM id 前缀;自动计数器的服务端与客户端取值可能不一致)。
审批组件的只读语义
ApprovalGate 的 decide 不传即只读 —— 不会发出任何请求,按钮不会假装成功。
接入方后端无法闭环时请显式保持只读:点了没反应,比功能少更伤信任。
主题
/* 放在 @tasklens/vue/style.css 之后 */
:root {
--tl-color-primary: oklch(0.52 0.19 320);
--tl-color-bg: #fafafa;
--tl-radius-md: 10px;
}源码分发(不装包)
不想引依赖?npx tasklens add agent-task-panel 把 .vue 源码直接拷进你的仓库,之后随你怎么改。
详见 tasklens CLI。
许可
MIT © 李学丹 · 仓库与完整文档
