Files
wehub-resource-sync bf9395e022
CI / license-header (push) Has been skipped
CI / e2e-dry-run (push) Has been skipped
CI / fast-gate (push) Failing after 0s
Test PR Label Logic / test-pr-labels (push) Failing after 1s
Skill Format Check / check-format (push) Failing after 2s
CI / security (push) Failing after 5s
CI / unit-test (push) Has been skipped
CI / lint (push) Has been skipped
CI / script-test (push) Has been skipped
CI / deterministic-gate (push) Has been skipped
CI / coverage (push) Has been skipped
CI / results (push) Has been cancelled
CI / deadcode (push) Has been cancelled
CI / e2e-live (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:22:54 +08:00

121 lines
8.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# lark-apps 云端会话开发
适用:用户希望让云端妙搭 Agent 生成或迭代应用,而不是把代码拉到本地开发。
## 核心流程
整个开发在云端进行:本地只负责「发消息 + 轮询状态」,不拉源码、不产出代码、不启动本地 dev server。所有 session/chat 命令都以用户身份执行(`--as user`)。
### 资源模型:app → session → turn
三层父子关系,下层都挂在上层之下:
- **app(应用资产)**:一个妙搭应用,由 `+create` 创建并拿到 `app_id`。云端生成应用类型用 `full_stack`
- **session(会话)**:一个 app 下的一段独立对话上下文,由 `+session-create` 创建并拿到 `session_id`。一个 app 可有多个 session`is_active` 表示该 session 当前是否可写(可发起对话)。
- **turn(轮)**:一个 session 里的一轮交互 = 一条用户消息 + 妙搭 Agent 针对它的生成/迭代。`+chat` 发一条消息就发起一轮;轮的句柄是 `turn_id`,状态看 `latest_turn.status`
### 执行模型:异步 + 轮询
`+chat` 把消息入队后**立即返回、不等生成完成,响应不带 `turn_id`**;本轮状态与轮询节奏全靠 `+session-get``latest_turn.status` / `is_streaming` / `next_poll_after_ms`
`+session-get` 关键字段:
- `is_streaming`:当前是否有一轮正在跑(`true`=还在生成)。
- `latest_turn.status`:最近一轮的状态,只有 `running` / `completed` / `failed` / `cancelled`
- `latest_turn.turn_id`:最近一轮的句柄(`+session-stop --turn-id` 用它)。
- `latest_turn.user_message`:本轮用户发的消息。
- `latest_turn.messages`:本轮完成后回看全貌的消息列表,按时序排列、每条带 `role`(用户消息、模型回复、工具调用等都在内,role 取值如 `user` / `assistant` / `tool`)。注意它在 `latest_turn` 仍 running/初始化期可能为空——该轮**进行中**的实时进展改用 `+session-messages-list --turn-id <latest_turn.turn_id>` 读(见下方轮询规则)。
- `queued_messages` / `queued_count`:还没开始跑、排在后面的消息。
- `next_poll_after_ms`:建议的下次轮询间隔(毫秒,固定值);非空时优先用它。
轮询规则:
- 节奏按 [初始化 vs 增量修改](#初始化-vs-增量修改) 判定:增量 5-10 秒一次;初始化 60-120 秒一次;`next_poll_after_ms` 非空时用它。
- `is_streaming=true``building` / `running` / `streaming` 表示仍在生成,继续轮询,不傻等也不提前放弃;初始化阶段单次 sleep 拉到 60-120 秒,进入 `streaming` 或属增量修改时切回 5-10 秒。
- `is_streaming=false``latest_turn.status=completed` 表示本轮完成,可发下一条。
- `failed` / `cancelled` 时转述错误字段或 hint,由用户决定是否重试,不要静默重发。
- 不知道某 app 有哪些 session 时,先 `+session-list --app-id <id>`,再选最近活跃的或让用户确认,别直接猜 `session_id`
- 要中止正在运行的一轮,从 `+session-get``latest_turn.turn_id` 取值,再调用 `+session-stop --turn-id <turn_id>`
- 状态与节奏看 `+session-get`,本轮实时内容看 `+session-messages-list`:想在 running 期间向用户播报"云端 Agent 此刻在做什么",用 `+session-messages-list --turn-id <latest_turn.turn_id>` 读已产出的增量消息(running 期间即可读,不必等本轮结束)。复用上面的轮询节奏、不另起更密的轮询;续拉时把上次响应的 `next_page_token``--page-token` 只取新消息,转述时简述进展、不原样打印整段消息或工具输出。
### 典型链路
```bash
# 1) 建 app,拿 app_id(云端生成走 full_stack
lark-cli apps +create --name "待办应用" --app-type full_stack \
--description "支持新增、完成、筛选待办"
# 2) 在该 app 下建 session,拿 session_id
lark-cli apps +session-create --app-id app_xxx
# 3) 发消息发起一轮(异步入队,立即返回,无 turn_id)
lark-cli apps +chat --app-id app_xxx --session-id sess_xxx --message "做一个待办清单页面"
# 4) 轮询本轮状态;完成后从 latest_turn.messages 读取结果
lark-cli apps +session-get --app-id app_xxx --session-id sess_xxx
# 找该 app 已有的会话(续聊/不确定 session 时用)
lark-cli apps +session-list --app-id app_xxx
```
## 完成态不等于发布态
通用发布态判定(is_published 语义、开发态链接拼接、发布态链接来源)见 SKILL.md「发布态护栏」。本 reference 只补云端会话特有的措辞:
- `+session-get` 返回 `is_streaming=false``latest_turn.status=completed`,只说明本轮云端生成/迭代结束,不等于已发布部署。
- 如果只完成了云端会话、没有确认发布完成,就明确告诉用户“开发态链接可进入继续编辑,发布态是否为最新版本尚未确认”。
## 需求发送
- 只有用户明确选择云端路径,或明确说“让妙搭 Agent / 云端 AI 生成/迭代”时,才进入本 reference;不要因为用户只说“做个 X”或“给我链接”就默认云端。
- 进入云端路径后,极简需求也可直接发起生成,例如“做个投票工具”“做个站会小应用”。先建 `full_stack` app,再用 `+chat --message "<用户原话>"` 透传需求,不编造实体、字段或业务细节。
- 如果需求过泛,可在 `+chat --message` 中保留原话,并只补一句“请先生成通用版本,后续可继续迭代”,不要用多轮追问阻塞生成。
## 会话落点
| 情形 | 动作 |
|---|---|
| 全新应用 + 云端生成 | 先 `+create --app-type full_stack``app_id`,再 `+session-create` -> `+chat` |
| 已知 app_id,用户没指定会话 | 先 `+session-list`;有活跃会话时问用户继续现有还是新开 |
| 用户说“新开一段/换个话题” | `+session-create` 后再 `+chat` |
| 用户说“接着刚才” | 复用上下文 session_id;拿不到就 `+session-list` 让用户选 |
| 用户问会话“进行到哪一步/当前状态/最新进展” | 用 `+session-get --session-id <sid>` 读状态。`+session-list` 只负责发现/选择会话,不含执行状态;它返回空不等于无状态可查(session_id 也可能来自上下文),别用 `+session-list`/`+release-list` 代替 `+session-get` 回答进度 |
## 初始化 vs 增量修改
`+chat` 单轮的耗时差距很大,取决于目标 app 是否**已初始化**。两者的轮询节奏不同,**`+chat` 前先把状态判定清楚**,不要拿"是不是第一次发消息"当代理判断——session 是新建的不代表 app 没初始化过。
### 判定规则
**已初始化**(满足任一即认为已初始化):
1. 本地存在该 app 的项目目录(已 `+init` 或 clone 过),**且** git commit 数 > 2
2. 应用维度(云端)至少有一个已提交的版本,按以下任一信号判断:
- `lark-cli apps +session-get --app-id <app_id> --session-id <session_id>` 的返回里出现已提交版本信息;
-`lark-cli apps +list`(必要时配 `--keyword <name>` 定位)的目标 app 条目里 `is_published: true`
**未初始化**(两个条件同时成立):
1. 本地不存在该 app 的项目目录;
2. 应用维度没有任何已提交版本(即上面两路云端信号都判 false)。
### 两种 `+chat` 的行为
| 状态 | 服务端动作 | 单轮耗时 | 轮询建议 |
|---|---|---|---|
| 已初始化 → **增量修改** | 云端 Agent 在已有云端工作区上对**已提交代码**做局部修改,跳过方案设计与首次生成 | 通常分钟级 | `next_poll_after_ms` 为空时 5-10 秒一次 |
| 未初始化 → **首次初始化 + 生成** | 服务端跑完整的应用初始化流程:需求分析、技术方案、数据模型、UI 与后端代码生成、首版代码提交到云端工作区 | 视需求复杂度,**通常 20~50 分钟** | `next_poll_after_ms` 为空时 60-120 秒一次 |
初始化阶段 `+session-get` 可能长时间持续返回 `building` / `running`,是正常状态,**不要按失败处理,也不要催用户**。
## 字段注意
所有字段统一 snake_case,顶层和嵌套 turn 字段都一样:`session_id``is_active``is_streaming``next_poll_after_ms``latest_turn.turn_id``latest_turn.status``latest_turn.user_message``latest_turn.messages`
`+session-stop` 只停止正在运行的当前轮,不关闭会话;停完仍可继续 `+chat`
## 不适用
- 用户已有本地 HTML/dist,要马上发布 URL:读 [`lark-apps-html-publish.md`](lark-apps-html-publish.md)。
- 用户要本地写代码、改仓库、跑 dev server:读 [`lark-apps-local-dev.md`](lark-apps-local-dev.md)。