Task Open(对话里开任务 / 看任务)
平台助手
platform-assistant的两个工具:把直聊开成任务(open_task)、 读用户自己的任务清单(list_tasks)。数据模型见 数据模型 §6。
两个 agent 的分工
platform-assistant(助手) | platform-demand-intake(受理器) | |
|---|---|---|
| 谁看得见 | 用户默认入口(侧栏第一条) | 只在任务对话里回复 |
| 会话类型 | kind=relation | kind=task |
| 工具 | open_task / list_tasks | build_plan / submit_request / submit_input_fact |
| 目的 | 回答问题、介绍平台、把需求开成任务 | 把需求收敛成结构化输入并出计划 |
两者不是同一个 agent 的两个名字:一个既要"可以只聊天"又要"替用户开工", 提示词与工具白名单只能互相妥协。分开之后边界是结构性的,不靠 prompt 自律。
open_task
open_task({ title, description })
→ { ok, status: 'created' | 'already_created', taskId, title }| 闸门 | 规则 |
|---|---|
| 通道 | 只在 metadata.channel === 'dialogue' |
| 身份 | owner 面不可用(维护 agent 的人不能替客户开任务) |
| agent | 只属于 platform-assistant |
| 任务上下文 | 必须没有 taskId:已有任务时该走受理器的 build_plan |
| 幂等 | 一轮只开一个(metadata.taskCreated),重复调用返回同一个 taskId |
产物:tasks 文档(dialogId=null,status=created,metadata.createdFrom='assistant-dialogue'
openedFromSessionId)+ 一条task.created日志(actor=agent,幂等键task.created:<taskId>)。turn 结果额外带taskCreated,前端据此刷新任务列表并跳到新任务。
list_tasks
list_tasks({ limit?: 1-20, status?: string })
→ { ok, count, tasks: [{ taskId, title, status, createdAt }], hint }- 只读:不建、不改、不推进任何任务;
- 只属于平台助手,且只在对话通道可用;
- 只能读自己的任务:
userId来自服务端会话metadata,模型无法指定别人的; - 读失败只降级(返回
list_failed),不让整轮对话失败。
存在理由:用户进来问的第一类问题往往不是"帮我做事",而是"我上次那个还在跑吗"。 没有这个工具,助手只能含糊其辞,用户就得自己去翻侧栏 —— 那它就只是个聊天窗口。
不变量
tasks.dialogId允许为null(没有 legacy Dialog),任务对话走agent_dialogues;- 日志写失败只降级:任务已建出来,不因为少一条审计把整轮对话判失败;
- 模块只依赖
TaskStoreModule/JournalModule两个叶子模块 ——TaskModule已经import AgentGatewayModule(主动播报要用对话服务), 反向依赖会成环。
代码落点
| 位置 | 说明 |
|---|---|
libs/modules/src/task-open/open-task.tool.ts | 开任务工具与四道闸 |
libs/modules/src/task-open/list-tasks.tool.ts | 只读的任务清单 |
libs/modules/src/task-open/services/task-open.service.ts | 建任务 + 写 task.created |
libs/modules/src/agent-gateway/services/agent-dialogue.service.ts | canOpenTask / canListTasks 装配 + turn 结果 taskCreated |
frontend/src/pages/workspace/index.tsx | 收到 taskCreated → 重拉列表并跳转;助手视图 URL 保持 /workspace |
测试证据
bash
npx jest libs/modules/src/task-open # 开任务 + 清单(20 例:闸门/幂等/文档形态/降级)
npx jest libs/modules/src/agent-gateway/services/agent-dialogue.service.spec.ts
# 助手挂 open_task+list_tasks;受理器只挂 build_plan已知边界
- 任务从直聊开出来后,任务会话是空的:需求正文在
description与task.created日志里。刻意不做消息搬运——同一句话不该在两条会话里各出现一次; open_task只建任务,不建计划。计划要等用户在任务里(或对话里)触发build_plan,走既有 prepare 链路;list_tasks只回状态,不解释原因:为什么卡住要看任务的发展日志(task_journal)。