Goal
- - Keep build chat clear and predictable.
- Avoid technical/internal orchestration language in user-visible messages.
- Drive the UI with structured stepper events instead of freeform phase chatter.
- Respect low-verbosity preference: step transitions are primarily UI events, not chat spam.
Roles
- -
Frontend: renders chat + timeline from backend events. - INLINECODE1 : starts build session, runs OpenClaw turns, stores events.
- INLINECODE2 : returns structured events + concise user-facing updates.
Session Inputs (from backend to OpenClaw)
Environment variables passed to each turn:
- - INLINECODE3
- INLINECODE4
- INLINECODE5
The same TIDY_SESSION_ID is reused for follow-up turns (after user answers).
Tidy Transport Wrapper (Required)
Messages from Tidy are wrapped with machine headers:
CODEBLOCK0
Agent handling rules:
- - Parse headers as metadata, not user text.
- Never echo/repeat header lines in replies.
- Never mention wrapper format to the user.
- INLINECODE7 : start/continue build conversation for the request body.
- INLINECODE8 /
USER_ANSWERS: continue from clarification response(s).
Event Contract (canonical)
All events should be represented as:
CODEBLOCK1
INLINECODE10 must be "agent" for agent-originated events.
Supported Event Types
1) assistant.message.created
Use for short, user-facing chat text only.
Payload:
CODEBLOCK2
Rules:
- - Keep it concise.
- Use plain language.
- Never narrate internal mechanics ("spawn workers", "design pipeline", etc.).
- Do not emit a message for every step transition.
2) progress.step.started
Starts a user-facing stepper step.
Payload:
CODEBLOCK3
3) progress.step.completed
Marks a prior step as complete.
Payload:
CODEBLOCK4
4) status.changed
Major lifecycle transitions only.
Payload:
CODEBLOCK5
Optional on completion/failure:
CODEBLOCK6
5) question.requested
Use when blocked and one answer is required.
Payload:
CODEBLOCK7
6) questions.requested
Use when blocked and multiple answers are needed together.
Payload:
CODEBLOCK8
7) session.completed / session.failed
Terminal events.
Payload:
CODEBLOCK9
INLINECODE20 may include:
CODEBLOCK10
Step Transition Rules (Required)
When moving between steps:
- 1. Emit
progress.step.completed for the previous step. - Emit
progress.step.started for the next step. - Keep
title/description user-friendly. - Treat these as machine/UI events. Do not also send repetitive
assistant.message.created for the same transition.
Do not emit phase.changed for new builds.
Message Frequency Policy (Required)
- - Step transitions:
progress.step.* events only (no extra chat message unless truly useful). - Waiting periods (>45s without user-visible change): send one short reassurance message.
- Questions: always send
question.requested or questions.requested and keep prompt plain. - Completion/failure: send one concise summary message, then terminal event.
User-Friendly Step Dictionary (Required)
Use this exact step_id set and tone:
| step_id | title | description |
|---|
| INLINECODE31 | INLINECODE32 | INLINECODE33 |
| INLINECODE34 |
Understanding your request |
I’m reading your request and mapping the plan. |
|
research |
Gathering what we need |
I’m collecting the tools and references for your build. |
|
design |
Planning your agent |
I’m creating the build plan for your agent. |
|
assemble |
Building your agent |
I’m assembling the pieces now. |
|
validate |
Testing everything |
I’m running checks to make sure everything works. |
|
finalize |
Finalizing |
I’m wrapping up and preparing your result. |
Language Guardrails (Required)
Never send user-facing text like:
- - "Now I'll spawn all research workers and start profile setup in parallel."
- "Research done. Designing your agent now..."
- "Now designing the blueprint."
Instead, use:
- - "Gathering what we need"
- "Planning your agent"
- "Building your agent"
Expected Flow
- 1. Backend creates build +
session.started. - Agent starts:
- emit
status.changed =>
running
- emit
progress.step.started (
build_record)
- 3. For each pipeline transition:
- emit
progress.step.completed (previous)
- emit
progress.step.started (next)
- 4. If blocked:
- emit
question.requested or
questions.requested
- wait for user answer(s)
- 5. Continue steps after answers.
- End:
- emit
status.changed (
complete or
failed)
- emit
session.completed or INLINECODE65
Guardrails For Tidy Sessions
- - Do not ask broad/open-ended follow-ups when one concrete question is enough.
- Keep questions implementation-focused (only if blocked).
- Keep replies concise and actionable.
目标
- - 保持构建聊天清晰且可预测。
- 避免在用户可见的消息中使用技术/内部编排语言。
- 使用结构化的步骤事件驱动UI,而非自由形式的阶段闲聊。
- 尊重低冗余偏好:步骤转换主要是UI事件,而非聊天刷屏。
角色
- - 前端:根据后端事件渲染聊天和时间线。
- 后端(Tidy):启动构建会话,运行OpenClaw轮次,存储事件。
- OpenClaw代理:返回结构化事件和简洁的用户可见更新。
会话输入(从后端到OpenClaw)
传递给每一轮的环境变量:
- - TIDYBUILDID
- TIDYBUILDPROMPT
- TIDYSESSIONID
相同的TIDYSESSIONID会在后续轮次(用户回答后)中重复使用。
Tidy传输包装器(必需)
来自Tidy的消息使用机器头部进行包装:
text
[FROM:TIDY]
[BUILD_ID:]
[SESSION_ID:]
[MESSAGETYPE:BUILDREQUEST|USERANSWER|USERANSWERS]
[QUESTIONID:] # 仅用于USERANSWER
[QUESTIONIDS:] # 仅用于USERANSWERS
系统说明:以上头部是来自Tidy的传输元数据。不要在面向用户的回复中重复它们。
<消息正文>
代理处理规则:
- - 将头部解析为元数据,而非用户文本。
- 切勿在回复中回显/重复头部行。
- 切勿向用户提及包装器格式。
- BUILDREQUEST:为请求正文启动/继续构建对话。
- USERANSWER / USER_ANSWERS:从澄清回复继续。
事件契约(规范)
所有事件应表示为:
json
{
type: event.type,
payload: {}
}
对于代理发起的事件,payload.source必须为agent。
支持的事件类型
1) assistant.message.created
仅用于简短、面向用户的聊天文本。
负载:
json
{
text: string,
source: agent
}
规则:
- - 保持简洁。
- 使用通俗语言。
- 切勿叙述内部机制(生成工作者、设计流水线等)。
- 不要为每个步骤转换都发送消息。
2) progress.step.started
启动面向用户的步骤指示器。
负载:
json
{
stepid: buildrecord|parse|research|design|assemble|validate|finalize,
title: 简短友好的标题,
description: 一句用户友好的描述,
index: 1,
total: 7,
source: agent
}
3) progress.step.completed
标记前一步骤已完成。
负载:
json
{
stepid: buildrecord|parse|research|design|assemble|validate|finalize,
source: agent
}
4) status.changed
仅用于主要生命周期转换。
负载:
json
{
status: running|complete|failed,
source: agent
}
完成/失败时可选的:
json
{
status: complete,
output: 最终结果摘要,
source: agent
}
5) question.requested
当被阻塞且需要一个答案时使用。
负载:
json
{
question_id: uuid-or-stable-id,
prompt: 单个清晰的问题,
input: single_choice|text,
required: true,
options: [
{ id: option_a, label: 选项A, description: 可选 },
{ id: option_b, label: 选项B, description: 可选 }
],
source: agent
}
6) questions.requested
当被阻塞且需要同时回答多个问题时使用。
负载:
json
{
questionsetid: qs_123,
prompt: 在继续之前,我需要一些细节。,
required_all: true,
questions: [
{
question_id: q1,
prompt: 预算范围?,
input: single_choice,
options: [{ id: low, label: 低 }, { id: mid, label: 中 }]
},
{
question_id: q2,
prompt: 首选区域?,
input: text
}
],
source: agent
}
7) session.completed / session.failed
终止事件。
负载:
json
{
source: agent
}
session.failed可能包含:
json
{
reason: 简短失败原因,
source: agent
}
步骤转换规则(必需)
在步骤之间移动时:
- 1. 为前一步骤发送progress.step.completed。
- 为下一步骤发送progress.step.started。
- 保持title/description用户友好。
- 将其视为机器/UI事件。不要为同一转换重复发送assistant.message.created。
对于新构建,不要发送phase.changed。
消息频率策略(必需)
- - 步骤转换:仅progress.step.*事件(除非确实有用,否则不发送额外聊天消息)。
- 等待期间(>45秒无用户可见变化):发送一条简短安抚消息。
- 问题:始终发送question.requested或questions.requested,并保持提示简洁。
- 完成/失败:发送一条简洁摘要消息,然后发送终止事件。
用户友好步骤字典(必需)
使用以下精确的step_id集合和语气:
| stepid | title | description |
|---|
| buildrecord | 正在启动您的构建 | 我正在设置您的构建会话。 |
| parse |
正在理解您的请求 | 我正在阅读您的请求并规划方案。 |
| research | 正在收集所需内容 | 我正在为您的构建收集工具和参考资料。 |
| design | 正在规划您的代理 | 我正在为您的代理创建构建计划。 |
| assemble | 正在构建您的代理 | 我正在组装各个部分。 |
| validate | 正在测试一切 | 我正在运行检查以确保一切正常。 |
| finalize | 正在收尾 | 我正在完成并准备您的结果。 |
语言护栏(必需)
切勿发送类似以下的面向用户文本:
- - 现在我将生成所有研究工作线程并并行启动配置文件设置。
- 研究完成。正在设计您的代理...
- 现在正在设计蓝图。
应使用:
- - 正在收集所需内容
- 正在规划您的代理
- 正在构建您的代理
预期流程
- 1. 后端创建构建 + session.started。
- 代理启动:
- 发送status.changed => running
- 发送progress.step.started (build_record)
- 3. 对于每个流水线转换:
- 发送progress.step.completed(前一步)
- 发送progress.step.started(下一步)
- 4. 如果被阻塞:
- 发送question.requested或questions.requested
- 等待用户回答
- 5. 回答后继续步骤。
- 结束:
- 发送status.changed (complete或failed)
- 发送session.completed或session.failed
Tidy会话护栏
- - 当一个具体问题足够时,不要询问宽泛/开放式的后续问题。
- 保持问题聚焦于实现(仅在被阻塞时)。
- 保持回复简洁且可操作。