Compare commits

...

9 Commits

Author SHA1 Message Date
lhk229 c8dc57a4e3 修复默认推理强度测试
Project CI / Native shell tests (pull_request) Has started running
Project CI / Repository checks (pull_request) Successful in 2m44s
Project CI / Frontend tests (pull_request) Successful in 3m34s
Project CI / Backend tests (pull_request) Successful in 6m36s
同步运行时配置测试对 high 默认 reasoning effort 的断言

保留策划 Agent 伪流式显示的降速调整
2026-09-13 10:47:41 +00:00
lhk229 114a016c57 调整LLM默认推理强度
Project CI / Frontend tests (pull_request) Failing after 2m15s
Project CI / Repository checks (pull_request) Failing after 2m24s
Project CI / Native shell tests (pull_request) Failing after 4m0s
Project CI / Backend tests (pull_request) Successful in 5m49s
将客户端未修改设置时的 reasoning effort 默认值从 max 调整为 high

同步前端配置草稿与 Rust 默认配置
2026-09-13 09:58:23 +00:00
lhk229 e878ec64cd Merge remote-tracking branch 'origin/master' into fix/design_agent
Project CI / Repository checks (pull_request) Successful in 2m13s
Project CI / Frontend tests (pull_request) Successful in 2m58s
Project CI / Backend tests (pull_request) Successful in 6m40s
Project CI / Native shell tests (pull_request) Successful in 17m29s
2026-09-13 09:37:07 +00:00
lhk229 731e3c3f00 强化阶段切换状态确认提示
审批通过后要求 Agent 先调用 get_workflow_status

在状态确认前禁止开始阶段工作或断言阶段状态
2026-09-13 09:36:27 +00:00
lhk229 c976a0944f 调整策划交互卡片位置
将审批卡和问询卡移动到输入框上方

拆分阶段状态与待处理操作并保持原有交互逻辑
2026-09-13 09:26:35 +00:00
lhk229 2589772d1a 优化策划Agent流式显示
将上游累计回复通过本地缓冲逐步呈现

避免大块流式响应一次性刷新并保持正常会话链路不变
2026-09-13 08:48:44 +00:00
lhk229 d9f1376beb 增强策划Agent流式调试记录
记录流式事件时间、序号、增量与累计文本长度及结束原因

扩大异步调试队列容量,保持调试写入不阻塞正常运行
2026-09-13 07:34:12 +00:00
lhk229 85e1503217 Merge remote-tracking branch 'origin/master' into fix/design_agent 2026-09-13 06:40:07 +00:00
lhk229 674cca428a 同步AGC客户端版本号
将客户端版本从 0.1.12 同步更新为 0.1.27

同步 package.json、Cargo.toml、Cargo.lock、tauri.conf.json 和 package-lock.json
2026-09-12 10:52:48 +00:00
14 changed files with 170 additions and 54 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@genarrative/ai-game-creator-shell",
"private": true,
"version": "0.1.12",
"version": "0.1.27",
"type": "module",
"scripts": {
"dev": "node scripts/start-tauri-dev.mjs",
+1 -1
View File
@@ -1725,7 +1725,7 @@ dependencies = [
[[package]]
name = "genarrative-ai-game-creator-shell"
version = "0.1.12"
version = "0.1.27"
dependencies = [
"agent-runtime-core",
"axum",
@@ -1,6 +1,6 @@
[package]
name = "genarrative-ai-game-creator-shell"
version = "0.1.12"
version = "0.1.27"
edition = "2021"
publish = false
@@ -229,15 +229,18 @@ fn prepare_design_decision(
}
if approved {
let phase = approve_design_phase(session, request_id)?;
let suffix = if phase == "consultant" {
""
} else {
"请开始该阶段工作。"
};
append_design_user(
session,
id,
format!("用户已批准上一阶段,现在进入 {phase} 阶段。{suffix}"),
if phase == "consultant" {
format!(
"用户已批准上一阶段,现在进入 {phase} 阶段。开始本轮工作前,先调用 get_workflow_status 确认 Runtime 当前阶段;在工具返回前,不要开始顾问工作或断言阶段状态。"
)
} else {
format!(
"用户已批准上一阶段,现在进入 {phase} 阶段。开始本轮工作前,先调用 get_workflow_status 确认 Runtime 当前阶段;在工具返回前,不要开始新阶段工作、写入文件、提交审批或断言阶段状态。"
)
},
);
begin_design_turn(session, id);
} else {
@@ -473,7 +476,7 @@ fn design_debug(root: &Path, kind: &str, data: Value) {
type Entry = (PathBuf, Value);
static QUEUE: OnceLock<std::sync::mpsc::SyncSender<Entry>> = OnceLock::new();
let sender = QUEUE.get_or_init(|| {
let (sender, receiver) = std::sync::mpsc::sync_channel::<Entry>(16);
let (sender, receiver) = std::sync::mpsc::sync_channel::<Entry>(256);
let _ = std::thread::Builder::new()
.name("design-debug".into())
.spawn(move || {
@@ -546,8 +549,26 @@ async fn request_design_provider(
None,
));
let result = if llm.stream {
let mut stream_sequence = 0_u64;
client
.stream_run(request.clone(), |delta| {
stream_sequence = stream_sequence.saturating_add(1);
design_debug(
root,
"stream",
json!({
"turnId": turn_id,
"requestIndex": session.turn.as_ref().map(|turn| turn.request_index),
"attempt": attempt,
"sequence": stream_sequence,
"occurredAtUnixNanos": unix_timestamp_nanos().to_string(),
"model": llm.model,
"deltaChars": delta.delta_text.chars().count(),
"accumulatedChars": delta.accumulated_text.chars().count(),
"deltaText": delta.delta_text,
"finishReason": delta.finish_reason,
}),
);
emit(design_event(
root,
&turn_id,
@@ -1499,7 +1499,7 @@ const GAME_CREATOR_APP_CONFIG_SCHEMA_VERSION: &str = "game-creator-config.v2";
const DEFAULT_GAME_CREATOR_LLM_BASE_URL: &str = "https://dev.genarrative.world/gpt/v1";
const DEFAULT_GAME_CREATOR_LLM_MODEL: &str = "gpt-6-astra";
const DEFAULT_GAME_CREATOR_LLM_API_KIND: &str = "openai_responses";
const DEFAULT_GAME_CREATOR_LLM_REASONING_EFFORT: &str = "max";
const DEFAULT_GAME_CREATOR_LLM_REASONING_EFFORT: &str = "high";
const DEFAULT_GAME_CREATOR_LLM_CONTEXT_WINDOW_TOKENS: u64 = 128_000;
const DEFAULT_GAME_CREATOR_LLM_AUTO_COMPACT_TOKEN_LIMIT: u64 = 64_000;
const DEFAULT_GAME_CREATOR_LLM_TOOL_OUTPUT_TOKEN_LIMIT: u64 = 12_000;
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "Genarrative AI Game Creator",
"version": "0.1.12",
"version": "0.1.27",
"identifier": "world.genarrative.ai-game-creator",
"build": {
"beforeDevCommand": "npm --prefix ../.. run agc:serve",
+46 -12
View File
@@ -762,7 +762,10 @@ export function App({
null,
);
planningV2SessionRef.current = planningV2Session;
const [planningV2TransientReply, setPlanningV2TransientReply] = useState('');
const [planningV2TransientReply, setPlanningV2TransientReplyVisible] =
useState('');
const planningV2TransientReplyTargetRef = useRef('');
const planningV2VisibleReplyRef = useRef('');
const [planningV2Reasoning, setPlanningV2Reasoning] = useState('');
const planningV2TurnRef = useRef<{
projectPath: string;
@@ -783,6 +786,37 @@ export function App({
>(),
);
function setPlanningV2TransientReplyTarget(next: string) {
planningV2TransientReplyTargetRef.current = next;
if (!next) {
planningV2VisibleReplyRef.current = '';
setPlanningV2TransientReplyVisible('');
}
}
useEffect(() => {
const timer = window.setInterval(() => {
const target = planningV2TransientReplyTargetRef.current;
setPlanningV2TransientReplyVisible((current) => {
if (!target) {
planningV2VisibleReplyRef.current = '';
return '';
}
const prefix = target.startsWith(current) ? current : '';
if (prefix === target) {
planningV2VisibleReplyRef.current = target;
return target;
}
const remaining = target.length - prefix.length;
const step = remaining > 160 ? 4 : remaining > 48 ? 2 : 1;
const next = target.slice(0, prefix.length + step);
planningV2VisibleReplyRef.current = next;
return next;
});
}, 50);
return () => window.clearInterval(timer);
}, []);
function applyPlanningV2CommandResult(
result: PlanningSessionCommandResultV2,
clientTurnId?: string,
@@ -951,7 +985,7 @@ export function App({
};
setChatAgentBusy(true);
setProjectSupervisorRuntimeError('');
setPlanningV2TransientReply('');
setPlanningV2TransientReplyTarget('');
try {
const view = await invoke<DesignView>('continue_design_agent_session', {
projectPath: nextProjectPath,
@@ -974,7 +1008,7 @@ export function App({
setPlanGddError(message);
} finally {
designAgentTurnRef.current = null;
setPlanningV2TransientReply('');
setPlanningV2TransientReplyTarget('');
setChatAgentBusy(false);
}
}
@@ -1465,7 +1499,7 @@ export function App({
setProjectSupervisorResponseStream(null);
setProjectSupervisorRuntimeError('');
setPlanningV2Session(null);
setPlanningV2TransientReply('');
setPlanningV2TransientReplyTarget('');
setPlanningV2Active(planningStartMode);
planningV2ActiveRef.current = planningStartMode;
designAgentLaneRef.current = planningStartMode;
@@ -1854,7 +1888,7 @@ export function App({
return;
}
if (payload.status === 'started') {
setPlanningV2TransientReply(
setPlanningV2TransientReplyTarget(
payload.accumulatedText || '正在生成策划方案…',
);
setProjectSupervisorRuntimeError('');
@@ -1863,7 +1897,7 @@ export function App({
payload.status === 'delta' &&
(payload.accumulatedText || payload.deltaText)
) {
setPlanningV2TransientReply(
setPlanningV2TransientReplyTarget(
payload.accumulatedText || payload.deltaText,
);
setProjectSupervisorRuntimeError('');
@@ -1912,13 +1946,13 @@ export function App({
return;
}
if (payload.kind === 'text' && payload.text != null) {
setPlanningV2TransientReply(payload.text);
setPlanningV2TransientReplyTarget(payload.text);
}
if (payload.reasoningText != null) {
setPlanningV2Reasoning(payload.reasoningText);
}
if (payload.kind === 'tool' && payload.text) {
setPlanningV2TransientReply(payload.text);
setPlanningV2TransientReplyTarget(payload.text);
}
if (payload.view) {
applyDesignView(payload.view, payload.projectPath);
@@ -5949,7 +5983,7 @@ export function App({
};
setChatAgentBusy(true);
setProjectSupervisorRuntimeError('');
setPlanningV2TransientReply('');
setPlanningV2TransientReplyTarget('');
try {
const result = currentSessionId
? await invoke<PlanningSessionCommandResultV2>(
@@ -6002,7 +6036,7 @@ export function App({
]);
} finally {
planningV2TurnRef.current = null;
setPlanningV2TransientReply('');
setPlanningV2TransientReplyTarget('');
setChatAgentBusy(false);
}
}
@@ -11674,7 +11708,7 @@ export function App({
projectPath: nextProjectPath,
clientTurnId,
};
setPlanningV2TransientReply('');
setPlanningV2TransientReplyTarget('');
setChatAgentBusy(true);
setPlanGddDecisionBusy(true);
void invoke<DesignView>('decide_design_phase', {
@@ -11715,7 +11749,7 @@ export function App({
return;
}
designAgentTurnRef.current = null;
setPlanningV2TransientReply('');
setPlanningV2TransientReplyTarget('');
setChatAgentBusy(false);
setPlanGddDecisionBusy(false);
});
@@ -25,23 +25,20 @@ type DesignAgentSurfaceProps = {
onRetry: () => void;
};
export function DesignAgentSurface({
type DesignAgentControlsProps = Pick<
DesignAgentSurfaceProps,
'view' | 'busy' | 'error' | 'onApprove' | 'onClarify' | 'onRetry'
>;
export function DesignAgentPhaseStatus({
view,
busy,
error,
onApprove,
onClarify,
onRetry,
}: DesignAgentSurfaceProps) {
const [clarifyText, setClarifyText] = useState('');
busy,
}: DesignAgentControlsProps) {
const phase = view?.session.currentPhase ?? 'concept';
const pending = view?.session.pendingApproval;
const clarification = view?.session.pendingClarification;
useLayoutEffect(() => {
setClarifyText('');
}, [clarification?.requestId]);
return (
<section className="design-agent-controls" aria-label="策划阶段控制">
<section className="design-agent-controls" aria-label="策划阶段状态">
<div className="design-agent-controls__header">
<div>
<span></span>
@@ -54,6 +51,42 @@ export function DesignAgentSurface({
) : null}
</div>
{error ? <p className="design-agent-controls__error">{error}</p> : null}
{view?.canRetry ? (
<button
className="design-agent-retry"
type="button"
disabled={busy}
onClick={onRetry}
>
<RotateCcw size={15} aria-hidden="true" />
</button>
) : null}
</section>
);
}
export function DesignAgentPendingActions({
view,
busy,
onApprove,
onClarify,
}: DesignAgentControlsProps) {
const [clarifyText, setClarifyText] = useState('');
const phase = view?.session.currentPhase ?? 'concept';
const pending = view?.session.pendingApproval;
const clarification = view?.session.pendingClarification;
useLayoutEffect(() => {
setClarifyText('');
}, [clarification?.requestId]);
if (!pending || phase === 'consultant') {
if (!clarification) return null;
}
return (
<section
className="design-agent-pending-actions"
aria-label="策划待处理事项"
>
{pending && phase !== 'consultant' ? (
<div className="design-agent-approval">
<p></p>
@@ -110,17 +143,26 @@ export function DesignAgentSurface({
</button>
</div>
) : null}
{view?.canRetry ? (
<button
className="design-agent-retry"
type="button"
disabled={busy}
onClick={onRetry}
>
<RotateCcw size={15} aria-hidden="true" />
</button>
) : null}
</section>
);
}
export function DesignAgentSurface({
view,
busy,
error,
onApprove,
onClarify,
onRetry,
}: DesignAgentSurfaceProps) {
return (
<DesignAgentPhaseStatus
view={view}
busy={busy}
error={error}
onApprove={onApprove}
onClarify={onClarify}
onRetry={onRetry}
/>
);
}
@@ -33,7 +33,10 @@ import {
ConversationModelSelect,
type ConversationModelSelectHandle,
} from './ConversationModelSelect';
import { DesignAgentSurface } from './DesignAgentSurface';
import {
DesignAgentPendingActions,
DesignAgentPhaseStatus,
} from './DesignAgentSurface';
import { PlanGddSurface } from './GddApprovalCard';
import {
pendingCommandDetail,
@@ -178,7 +181,7 @@ export function ProjectSupervisorView({
>
<div className="project-supervisor-conversation">
{designView || onDesignApprove ? (
<DesignAgentSurface
<DesignAgentPhaseStatus
view={designView}
busy={runtimePanelProps.controlBusy || planGddDecisionBusy}
error={planGddError}
@@ -359,6 +362,16 @@ export function ProjectSupervisorView({
</button>
</div>
) : null}
{designView || onDesignApprove ? (
<DesignAgentPendingActions
view={designView}
busy={runtimePanelProps.controlBusy || planGddDecisionBusy}
error={planGddError}
onApprove={onDesignApprove ?? (() => undefined)}
onClarify={onDesignClarify ?? (() => undefined)}
onRetry={onDesignRetry ?? (() => undefined)}
/>
) : null}
<form
className="project-supervisor-composer"
onSubmit={(event) => {
@@ -52,7 +52,7 @@ const defaultRuntimeConfigDraft: GameCreatorAppConfig = {
baseUrl: '',
model: '',
apiKind: 'openai_responses',
reasoningEffort: 'max',
reasoningEffort: 'high',
stream: true,
webSearchEnabled: true,
contextWindowTokens: 128000,
@@ -8551,6 +8551,12 @@ button.design-workspace-tree__entry:hover,
padding: 0;
}
.design-agent-pending-actions {
display: grid;
gap: 10px;
margin-top: 2px;
}
.design-agent-approval p,
.design-agent-clarify p {
margin: 0;
@@ -620,7 +620,7 @@ function createProjectSupervisorRuntimeHarness({
baseUrl: '',
model: 'quality',
apiKind: 'openai_responses',
reasoningEffort: 'max',
reasoningEffort: 'high',
stream: true,
webSearchEnabled: true,
contextWindowTokens: 128000,
@@ -1000,7 +1000,7 @@ export function registerPublishedRuntimeSettingsTests() {
expect(screen.queryByLabelText('LLM API Key')).toBeNull();
expect(screen.queryByLabelText('LLM Base URL')).toBeNull();
expect(screen.queryByLabelText('LLM 模型')).toBeNull();
expect(screen.getByLabelText('推理档')).toHaveProperty('value', 'max');
expect(screen.getByLabelText('推理档')).toHaveProperty('value', 'high');
expect(screen.getByLabelText('联网检索')).toHaveProperty('checked', true);
fireEvent.click(screen.getByRole('button', { name: /Agent 分工/ }));
expect(screen.getByText('所有角色使用统一账号服务')).not.toBeNull();
@@ -1031,7 +1031,7 @@ export function registerPublishedRuntimeSettingsTests() {
baseUrl: '',
model: '',
apiKind: 'openai_responses',
reasoningEffort: 'max',
reasoningEffort: 'high',
stream: true,
webSearchEnabled: true,
contextWindowTokens: 128000,
+1 -1
View File
@@ -95,7 +95,7 @@
},
"apps/ai-game-creator-shell": {
"name": "@genarrative/ai-game-creator-shell",
"version": "0.1.12",
"version": "0.1.27",
"dependencies": {
"@cubone/react-file-manager": "^1.35.0",
"@genarrative/image-canvas-core": "0.1.0",