补充下一步建议命令
新增聊天侧next命令基于当前状态给出安全草稿建议 补充主窗口下一步建议测试和帮助命令覆盖 同步AI游戏创作App技术方案和共享决策记录
This commit is contained in:
@@ -1825,6 +1825,7 @@ const chatCommandHelp = [
|
||||
'/capabilities:查看 Agent 能力清单',
|
||||
'/audit:审计当前项目的 Agent 能力证据',
|
||||
'/status:查看项目状态',
|
||||
'/next:查看下一步建议',
|
||||
'/open-project:在系统文件管理器中显示项目目录',
|
||||
'/switch-project:回到项目启动器切换工作区',
|
||||
'/index:刷新本地项目索引',
|
||||
@@ -1972,6 +1973,78 @@ function summarizeProjectStatus(
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
function summarizeNextProjectActions(
|
||||
nextManifest: GameCreationAppManifest,
|
||||
trace: GameCreationAgentRunTrace | null,
|
||||
) {
|
||||
const suggestions: Array<{ label: string; command?: string }> = [];
|
||||
const addSuggestion = (label: string, command?: string) => {
|
||||
if (command && suggestions.some((item) => item.command === command)) {
|
||||
return;
|
||||
}
|
||||
suggestions.push({ label, command });
|
||||
};
|
||||
|
||||
const preview = nextManifest.preview;
|
||||
if (!trace) {
|
||||
addSuggestion('直接输入一句游戏需求,确认后生成首版原型');
|
||||
} else if (
|
||||
trace.lifecycleStatus === 'killed' ||
|
||||
trace.status === 'failed' ||
|
||||
trace.stopReason === 'max-passes-exhausted'
|
||||
) {
|
||||
addSuggestion('补充说明并继续最近 run', '/agent-resume ');
|
||||
} else if (
|
||||
trace.status === 'passed' ||
|
||||
trace.status === 'artifacts-written' ||
|
||||
trace.stopReason === 'evaluator-passed'
|
||||
) {
|
||||
addSuggestion(
|
||||
preview?.status === 'running' && preview.url
|
||||
? '打开当前本地预览'
|
||||
: '运行自检并启动本地预览',
|
||||
preview?.status === 'running' && preview.url ? '/open-preview' : '/run',
|
||||
);
|
||||
} else {
|
||||
addSuggestion('查看最近 loop 进展', '/trace');
|
||||
}
|
||||
|
||||
const readyTasks = selectGameCreationAppReadyTasks({
|
||||
tasks: taskRowsFromManifest(nextManifest),
|
||||
});
|
||||
if (readyTasks.length > 0) {
|
||||
addSuggestion(`查看 ${readyTasks.length} 个 ready 任务`, '/tasks');
|
||||
} else {
|
||||
addSuggestion('查看任务拆分和等待项', '/tasks');
|
||||
}
|
||||
|
||||
if (nextManifest.assets.length > 0) {
|
||||
addSuggestion(`查看 ${nextManifest.assets.length} 个本地资产`, '/assets');
|
||||
} else {
|
||||
addSuggestion(
|
||||
'登记本地素材或同步画板资源',
|
||||
'/asset-register assets/hero.png image image/png',
|
||||
);
|
||||
addSuggestion('同步已有画板项目资源', '/sync-canvas-project ');
|
||||
}
|
||||
|
||||
if (trace) {
|
||||
addSuggestion('查看最近 trace 摘要', '/trace');
|
||||
addSuggestion('列出最近 Run 产物', '/run-artifacts');
|
||||
}
|
||||
addSuggestion('打开产物命令列表', '/artifacts');
|
||||
addSuggestion('打开日志命令列表', '/logs');
|
||||
|
||||
const firstCommand = suggestions.find((item) => item.command);
|
||||
return {
|
||||
text: `下一步建议:\n${suggestions
|
||||
.map((item) => `- ${item.label}${item.command ? `:${item.command}` : ''}`)
|
||||
.join('\n')}`,
|
||||
draftCommand: firstCommand?.command,
|
||||
draftCommandLabel: firstCommand?.label,
|
||||
};
|
||||
}
|
||||
|
||||
function summarizeMainProjectHeader(
|
||||
nextManifest: GameCreationAppManifest,
|
||||
agents: AgentStatusCard[],
|
||||
@@ -5215,6 +5288,23 @@ export function App() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (prompt === '/next') {
|
||||
if (!requireChatProjectForUserAction()) {
|
||||
return;
|
||||
}
|
||||
const summary = summarizeNextProjectActions(manifest, agentRunTrace);
|
||||
setMessages((current) => [
|
||||
...current,
|
||||
{
|
||||
role: 'assistant',
|
||||
text: summary.text,
|
||||
draftCommand: summary.draftCommand,
|
||||
draftCommandLabel: summary.draftCommandLabel,
|
||||
},
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (prompt === '/index') {
|
||||
void queueOrExecuteProjectIndex();
|
||||
return;
|
||||
|
||||
@@ -2119,6 +2119,27 @@ describe('AI 游戏创作 App 界面边界', () => {
|
||||
expect(await screen.findByText(/项目:未命名游戏原型/)).not.toBeNull();
|
||||
expect(screen.getByText(/目录:\/tmp\/authorized-game/)).not.toBeNull();
|
||||
|
||||
const runLocalCountBeforeNext = invoke.mock.calls.filter(
|
||||
([command]) => command === 'run_limited_local_command',
|
||||
).length;
|
||||
submitChat('/next');
|
||||
expect(await screen.findByText(/下一步建议:/)).not.toBeNull();
|
||||
expect(screen.getByText(/运行自检并启动本地预览:\/run/)).not.toBeNull();
|
||||
expect(screen.getByText(/查看 .* 个 ready 任务:\/tasks/)).not.toBeNull();
|
||||
const nextMessageList = document.querySelector('.message-list');
|
||||
expect(nextMessageList).not.toBeNull();
|
||||
fireEvent.click(
|
||||
within(nextMessageList as HTMLElement).getByRole('button', {
|
||||
name: '运行自检并启动本地预览',
|
||||
}),
|
||||
);
|
||||
expect(screen.getByLabelText('创作想法')).toHaveProperty('value', '/run');
|
||||
expect(
|
||||
invoke.mock.calls.filter(
|
||||
([command]) => command === 'run_limited_local_command',
|
||||
),
|
||||
).toHaveLength(runLocalCountBeforeNext);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '权限' }));
|
||||
expect(
|
||||
await screen.findByText(/策略:\.agent\/policy\.json/),
|
||||
@@ -7675,6 +7696,7 @@ describe('AI 游戏创作 App 界面边界', () => {
|
||||
expect(
|
||||
screen.getByText(/\/switch-project:回到项目启动器切换工作区/),
|
||||
).not.toBeNull();
|
||||
expect(screen.getByText(/\/next:查看下一步建议/)).not.toBeNull();
|
||||
expect(
|
||||
screen.getByText(
|
||||
/\/asset-register 路径 \[kind\] \[mediaType\]:登记项目内已有资产/,
|
||||
|
||||
@@ -3861,6 +3861,7 @@
|
||||
- 2026-07-03 调整:单 Agent 对话面板允许用户把当前输入手动追加到该 agent 的 `memory/agents/<group>/<role>.md` 私有记忆;写入复用 `memory.write` 项目策略、项目锁和 Tauri 本地目录能力,不把普通对话流水自动混入私有记忆;聊天侧 `/agent-conversations` 和 `/agent-memories` 只列出同一批 Agent 对话与私有记忆读取命令并提供首个 `/read` 草稿,不直接读取文件。
|
||||
- 2026-07-03 调整:主窗口新增音效登记和画板音频导入快捷入口,只填入 `/asset-register assets/audio/sfx.wav audio audio/wav` 或 `/import-canvas-asset assets/audio/sfx.wav ` 草稿;音乐组仍复用现有资产登记 / 画板回流链路,不新增独立音频生成系统。
|
||||
- 2026-07-03 调整:主窗口新增常用生成产物读取入口,只把入口 HTML、设计、数值、美术清单、音频清单和发布说明对应的 `/read` 草稿填入聊天输入框;聊天命令 `/artifacts` 只列出同一组固定读取命令并提供首个读取草稿,`/run-artifacts` 只列出最近 trace 里的产物读取命令并提供首个 `/read` 草稿,`/logs` 只列出固定日志读取命令;实际读取仍走聊天侧 `file.read` 权限流,不直接读本地文件。
|
||||
- 2026-07-03 调整:普通用户通过聊天输入 `/next` 触发下一步建议入口,只基于主窗口当前已加载的 manifest、最近 run trace 和最近命令摘要生成聊天建议,列出 `/tasks`、`/trace`、`/run`、`/open-preview`、`/assets`、`/artifacts`、`/run-artifacts`、`/logs`、`/agent-resume ` 等安全命令草稿方向,并提供一个首选草稿;该命令不得直接执行 Tauri 读写、启动或打开预览、读取本地文件,也不得绕过原有命令确认和 `file.read` 权限流。
|
||||
- 2026-06-25 调整:本地 HTTP 预览静态 `HEAD` 必须返回与 `GET` 相同的真实 `Content-Length`,但不返回 body;浏览器、图片、音频和视频探测不能拿到 `Content-Length: 0` 的假响应。
|
||||
- 2026-06-25 调整:普通用户通过聊天输入 `/run` 触发待确认 `game.run_local`,确认后只能复用白名单 `game.static_smoke` 自检当前 `game/index.html`,通过后启动 `127.0.0.1` 本地 HTTP 预览。独立执行 `game.static_smoke` 时如果已有 `.agent/run.latest.json`,必须追加 `Playtest / game.static_smoke` trace step,避免“运行了代码但编排 trace 不可见”。
|
||||
- 2026-06-25 调整:普通用户通过聊天输入 `/trace` 触发只读 `agent.trace_read`,读取 `.agent/run.latest.json` 并在聊天里摘要 loop 轮次、stopReason、nextStep、active / carry-over 任务、repairRoutes、agent 建议命令和最近 step。trace 面板仍只在开发窗口展示,普通用户窗口不新增面板。
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user