feat: unify creation agent chat fill
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* @vitest-environment jsdom */
|
||||
/* @vitest-environment jsdom */
|
||||
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
@@ -81,11 +81,12 @@ test('big fish workspace submits quick keyword fill request after two turns', as
|
||||
/>,
|
||||
);
|
||||
|
||||
await user.click(screen.getByRole('button', { name: '补充剩余关键字' }));
|
||||
await user.click(screen.getByRole('button', { name: '补充剩余设定' }));
|
||||
|
||||
expect(onSubmitMessage).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
text: '请补充剩余关键字。',
|
||||
text: '请补充剩余设定。',
|
||||
quickFillRequested: true,
|
||||
}),
|
||||
);
|
||||
});
|
||||
@@ -100,5 +101,5 @@ test('big fish workspace hides keyword fill before two turns', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.queryByRole('button', { name: '补充剩余关键字' })).toBeNull();
|
||||
expect(screen.queryByRole('button', { name: '补充剩余设定' })).toBeNull();
|
||||
});
|
||||
|
||||
@@ -4,7 +4,12 @@ import type {
|
||||
ExecuteBigFishActionRequest,
|
||||
SendBigFishMessageRequest,
|
||||
} from '../../../packages/shared/src/contracts/bigFish';
|
||||
import { createCreationAgentClientMessageId } from '../../services/creation-agent';
|
||||
import {
|
||||
buildCreationAgentChatMessage,
|
||||
createCreationAgentChatQuickActions,
|
||||
createCreationAgentClientMessageId,
|
||||
resolveCreationAgentQuickActionMessage,
|
||||
} from '../../services/creation-agent';
|
||||
import {
|
||||
type CreationAgentAnchorView,
|
||||
type CreationAgentSessionView,
|
||||
@@ -84,35 +89,30 @@ export function BigFishAgentWorkspace({
|
||||
isStreamingReply={Boolean(streamingReplyText)}
|
||||
isBusy={isBusy}
|
||||
error={error}
|
||||
quickActions={[
|
||||
{
|
||||
key: 'summarize',
|
||||
label: '总结当前设定',
|
||||
},
|
||||
{
|
||||
key: 'quickFill',
|
||||
label: '补充剩余关键字',
|
||||
minTurn: 2,
|
||||
},
|
||||
]}
|
||||
quickActions={createCreationAgentChatQuickActions()}
|
||||
onBack={onBack}
|
||||
onSubmitText={(text) => {
|
||||
onSubmitMessage({
|
||||
clientMessageId: createCreationAgentClientMessageId('big-fish'),
|
||||
text,
|
||||
});
|
||||
onSubmitMessage(
|
||||
buildCreationAgentChatMessage({
|
||||
clientMessageId: createCreationAgentClientMessageId('big-fish'),
|
||||
text,
|
||||
}),
|
||||
);
|
||||
}}
|
||||
onPrimaryAction={() => {
|
||||
onExecuteAction({ action: 'big_fish_compile_draft' });
|
||||
}}
|
||||
onQuickAction={(action) => {
|
||||
onSubmitMessage({
|
||||
clientMessageId: createCreationAgentClientMessageId('big-fish'),
|
||||
text:
|
||||
action.key === 'quickFill'
|
||||
? '请补充剩余关键字。'
|
||||
: '请总结一下当前已经成形的大鱼吃小鱼设定。',
|
||||
});
|
||||
const quickActionMessage = resolveCreationAgentQuickActionMessage(
|
||||
action.key,
|
||||
'请总结一下当前已经成形的大鱼吃小鱼设定。',
|
||||
);
|
||||
onSubmitMessage(
|
||||
buildCreationAgentChatMessage({
|
||||
clientMessageId: createCreationAgentClientMessageId('big-fish'),
|
||||
...quickActionMessage,
|
||||
}),
|
||||
);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
/* @vitest-environment jsdom */
|
||||
/* @vitest-environment jsdom */
|
||||
|
||||
import { fireEvent, render, screen } from '@testing-library/react';
|
||||
import { afterEach, expect, test, vi } from 'vitest';
|
||||
|
||||
import { createCreationAgentChatQuickActions } from '../../services/creation-agent';
|
||||
|
||||
import {
|
||||
type CreationAgentTheme,
|
||||
CreationAgentWorkspace,
|
||||
@@ -243,17 +245,7 @@ test('creation agent workspace shows primary and progress actions at completed p
|
||||
loadingText="正在准备"
|
||||
composerPlaceholder="输入消息"
|
||||
primaryActionLabel="生成结果页"
|
||||
quickActions={[
|
||||
{
|
||||
key: 'summarize',
|
||||
label: '总结当前设定',
|
||||
},
|
||||
{
|
||||
key: 'quickFill',
|
||||
label: '补全剩余设定',
|
||||
minTurn: 2,
|
||||
},
|
||||
]}
|
||||
quickActions={createCreationAgentChatQuickActions()}
|
||||
onBack={() => {}}
|
||||
onSubmitText={() => {}}
|
||||
onPrimaryAction={() => {}}
|
||||
@@ -262,7 +254,7 @@ test('creation agent workspace shows primary and progress actions at completed p
|
||||
|
||||
expect(screen.getByRole('button', { name: '生成结果页' })).toBeTruthy();
|
||||
expect(screen.getByRole('button', { name: '总结当前设定' })).toBeTruthy();
|
||||
expect(screen.getByRole('button', { name: '补全剩余设定' })).toBeTruthy();
|
||||
expect(screen.getByRole('button', { name: '补充剩余设定' })).toBeTruthy();
|
||||
});
|
||||
|
||||
test('creation agent workspace hides hero copy area when title and summary are absent', () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* @vitest-environment jsdom */
|
||||
/* @vitest-environment jsdom */
|
||||
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
@@ -108,11 +108,11 @@ test('workspace enables quick fill after at least two turns and submits quick fi
|
||||
/>,
|
||||
);
|
||||
|
||||
await user.click(screen.getByRole('button', { name: '补全剩余设定' }));
|
||||
await user.click(screen.getByRole('button', { name: '补充剩余设定' }));
|
||||
|
||||
expect(onSubmitMessage).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
text: '请补全剩余设定。',
|
||||
text: '请补充剩余设定。',
|
||||
quickFillRequested: true,
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -5,8 +5,11 @@ import type {
|
||||
SendCustomWorldAgentMessageRequest,
|
||||
} from '../../../packages/shared/src/contracts/customWorldAgent';
|
||||
import {
|
||||
buildCreationAgentChatMessage,
|
||||
createCreationAgentChatQuickActions,
|
||||
createCreationAgentClientMessageId,
|
||||
isCreationAgentOperationBusy,
|
||||
resolveCreationAgentQuickActionMessage,
|
||||
} from '../../services/creation-agent';
|
||||
import {
|
||||
type CreationAgentAnchorView,
|
||||
@@ -166,13 +169,17 @@ export function CustomWorldAgentWorkspace({
|
||||
isCreationAgentOperationBusy(activeOperation) || isStreamingReply;
|
||||
|
||||
const submitMessage = (text: string, quickFillRequested = false) => {
|
||||
onSubmitMessage({
|
||||
clientMessageId: createCreationAgentClientMessageId('custom-world'),
|
||||
text,
|
||||
quickFillRequested,
|
||||
focusCardId: null,
|
||||
selectedCardIds: [],
|
||||
});
|
||||
onSubmitMessage(
|
||||
buildCreationAgentChatMessage({
|
||||
clientMessageId: createCreationAgentClientMessageId('custom-world'),
|
||||
text,
|
||||
quickFillRequested,
|
||||
extraPayload: {
|
||||
focusCardId: null,
|
||||
selectedCardIds: [],
|
||||
},
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -186,17 +193,7 @@ export function CustomWorldAgentWorkspace({
|
||||
streamingReplyText={streamingReplyText}
|
||||
isStreamingReply={isStreamingReply}
|
||||
isBusy={isBusy}
|
||||
quickActions={[
|
||||
{
|
||||
key: 'summarize',
|
||||
label: '总结当前设定',
|
||||
},
|
||||
{
|
||||
key: 'quickFill',
|
||||
label: '补全剩余设定',
|
||||
minTurn: 2,
|
||||
},
|
||||
]}
|
||||
quickActions={createCreationAgentChatQuickActions()}
|
||||
onBack={onBack}
|
||||
onSubmitText={(text) => {
|
||||
submitMessage(text);
|
||||
@@ -207,12 +204,14 @@ export function CustomWorldAgentWorkspace({
|
||||
});
|
||||
}}
|
||||
onQuickAction={(action) => {
|
||||
if (action.key === 'quickFill') {
|
||||
submitMessage('请补全剩余设定。', true);
|
||||
return;
|
||||
}
|
||||
|
||||
submitMessage('请总结一下当前已经成形的世界设定。');
|
||||
const quickActionMessage = resolveCreationAgentQuickActionMessage(
|
||||
action.key,
|
||||
'请总结一下当前已经成形的世界设定。',
|
||||
);
|
||||
submitMessage(
|
||||
quickActionMessage.text,
|
||||
quickActionMessage.quickFillRequested,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* @vitest-environment jsdom */
|
||||
/* @vitest-environment jsdom */
|
||||
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
@@ -80,11 +80,12 @@ test('puzzle workspace submits quick keyword fill request after two turns', asyn
|
||||
/>,
|
||||
);
|
||||
|
||||
await user.click(screen.getByRole('button', { name: '补充剩余关键字' }));
|
||||
await user.click(screen.getByRole('button', { name: '补充剩余设定' }));
|
||||
|
||||
expect(onSubmitMessage).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
text: '请补充剩余关键字。',
|
||||
text: '请补充剩余设定。',
|
||||
quickFillRequested: true,
|
||||
}),
|
||||
);
|
||||
});
|
||||
@@ -99,5 +100,5 @@ test('puzzle workspace hides keyword fill before two turns', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.queryByRole('button', { name: '补充剩余关键字' })).toBeNull();
|
||||
expect(screen.queryByRole('button', { name: '补充剩余设定' })).toBeNull();
|
||||
});
|
||||
|
||||
@@ -6,7 +6,12 @@ import type {
|
||||
PuzzleAgentSessionSnapshot,
|
||||
SendPuzzleAgentMessageRequest,
|
||||
} from '../../../packages/shared/src/contracts/puzzleAgentSession';
|
||||
import { createCreationAgentClientMessageId } from '../../services/creation-agent';
|
||||
import {
|
||||
buildCreationAgentChatMessage,
|
||||
createCreationAgentChatQuickActions,
|
||||
createCreationAgentClientMessageId,
|
||||
resolveCreationAgentQuickActionMessage,
|
||||
} from '../../services/creation-agent';
|
||||
import {
|
||||
type CreationAgentOperationView,
|
||||
type CreationAgentSessionView,
|
||||
@@ -100,35 +105,30 @@ export function PuzzleAgentWorkspace({
|
||||
isStreamingReply={Boolean(streamingReplyText)}
|
||||
isBusy={isBusy}
|
||||
error={error}
|
||||
quickActions={[
|
||||
{
|
||||
key: 'summarize',
|
||||
label: '总结当前设定',
|
||||
},
|
||||
{
|
||||
key: 'quickFill',
|
||||
label: '补充剩余关键字',
|
||||
minTurn: 2,
|
||||
},
|
||||
]}
|
||||
quickActions={createCreationAgentChatQuickActions()}
|
||||
onBack={onBack}
|
||||
onSubmitText={(text) => {
|
||||
onSubmitMessage({
|
||||
clientMessageId: createCreationAgentClientMessageId('puzzle'),
|
||||
text,
|
||||
});
|
||||
onSubmitMessage(
|
||||
buildCreationAgentChatMessage({
|
||||
clientMessageId: createCreationAgentClientMessageId('puzzle'),
|
||||
text,
|
||||
}),
|
||||
);
|
||||
}}
|
||||
onPrimaryAction={() => {
|
||||
onExecuteAction({ action: 'compile_puzzle_draft' });
|
||||
}}
|
||||
onQuickAction={(action) => {
|
||||
onSubmitMessage({
|
||||
clientMessageId: createCreationAgentClientMessageId('puzzle'),
|
||||
text:
|
||||
action.key === 'quickFill'
|
||||
? '请补充剩余关键字。'
|
||||
: '请总结一下当前已经成形的拼图设定。',
|
||||
});
|
||||
const quickActionMessage = resolveCreationAgentQuickActionMessage(
|
||||
action.key,
|
||||
'请总结一下当前已经成形的拼图设定。',
|
||||
);
|
||||
onSubmitMessage(
|
||||
buildCreationAgentChatMessage({
|
||||
clientMessageId: createCreationAgentClientMessageId('puzzle'),
|
||||
...quickActionMessage,
|
||||
}),
|
||||
);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
58
src/services/creation-agent/creationAgentChat.test.ts
Normal file
58
src/services/creation-agent/creationAgentChat.test.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import {
|
||||
CREATION_AGENT_QUICK_FILL_MESSAGE,
|
||||
buildCreationAgentChatMessage,
|
||||
createCreationAgentChatQuickActions,
|
||||
resolveCreationAgentQuickActionMessage,
|
||||
} from './creationAgentChat';
|
||||
|
||||
test('creation agent chat exposes the unified summary and quick fill actions', () => {
|
||||
expect(createCreationAgentChatQuickActions()).toEqual([
|
||||
{
|
||||
key: 'summarize',
|
||||
label: '总结当前设定',
|
||||
},
|
||||
{
|
||||
key: 'quickFill',
|
||||
label: '补充剩余设定',
|
||||
minTurn: 2,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
test('creation agent chat resolves quick actions through one message contract', () => {
|
||||
expect(
|
||||
resolveCreationAgentQuickActionMessage('quickFill', '请总结当前设定。'),
|
||||
).toEqual({
|
||||
text: CREATION_AGENT_QUICK_FILL_MESSAGE,
|
||||
quickFillRequested: true,
|
||||
});
|
||||
|
||||
expect(
|
||||
resolveCreationAgentQuickActionMessage('summarize', '请总结当前设定。'),
|
||||
).toEqual({
|
||||
text: '请总结当前设定。',
|
||||
quickFillRequested: false,
|
||||
});
|
||||
});
|
||||
|
||||
test('creation agent chat builds shared message payload with genre extras', () => {
|
||||
expect(
|
||||
buildCreationAgentChatMessage({
|
||||
clientMessageId: 'message-1',
|
||||
text: '请补充剩余设定。',
|
||||
quickFillRequested: true,
|
||||
extraPayload: {
|
||||
focusCardId: null,
|
||||
selectedCardIds: [],
|
||||
},
|
||||
}),
|
||||
).toEqual({
|
||||
clientMessageId: 'message-1',
|
||||
text: '请补充剩余设定。',
|
||||
quickFillRequested: true,
|
||||
focusCardId: null,
|
||||
selectedCardIds: [],
|
||||
});
|
||||
});
|
||||
63
src/services/creation-agent/creationAgentChat.ts
Normal file
63
src/services/creation-agent/creationAgentChat.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
export const CREATION_AGENT_SUMMARY_ACTION_KEY = 'summarize';
|
||||
export const CREATION_AGENT_QUICK_FILL_ACTION_KEY = 'quickFill';
|
||||
|
||||
export const CREATION_AGENT_SUMMARY_ACTION_LABEL = '总结当前设定';
|
||||
export const CREATION_AGENT_QUICK_FILL_ACTION_LABEL = '补充剩余设定';
|
||||
export const CREATION_AGENT_QUICK_FILL_MESSAGE = '请补充剩余设定。';
|
||||
|
||||
type CreationAgentChatQuickAction = {
|
||||
key: string;
|
||||
label: string;
|
||||
minTurn?: number;
|
||||
};
|
||||
|
||||
type CreationAgentChatMessageBase = {
|
||||
clientMessageId: string;
|
||||
text: string;
|
||||
quickFillRequested?: boolean;
|
||||
};
|
||||
|
||||
export function createCreationAgentChatQuickActions(): CreationAgentChatQuickAction[] {
|
||||
return [
|
||||
{
|
||||
key: CREATION_AGENT_SUMMARY_ACTION_KEY,
|
||||
label: CREATION_AGENT_SUMMARY_ACTION_LABEL,
|
||||
},
|
||||
{
|
||||
key: CREATION_AGENT_QUICK_FILL_ACTION_KEY,
|
||||
label: CREATION_AGENT_QUICK_FILL_ACTION_LABEL,
|
||||
minTurn: 2,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export function resolveCreationAgentQuickActionMessage(
|
||||
actionKey: string,
|
||||
summaryMessage: string,
|
||||
) {
|
||||
const quickFillRequested = actionKey === CREATION_AGENT_QUICK_FILL_ACTION_KEY;
|
||||
|
||||
return {
|
||||
text: quickFillRequested ? CREATION_AGENT_QUICK_FILL_MESSAGE : summaryMessage,
|
||||
quickFillRequested,
|
||||
};
|
||||
}
|
||||
|
||||
export function buildCreationAgentChatMessage<TExtraPayload extends object = Record<string, never>>({
|
||||
clientMessageId,
|
||||
text,
|
||||
quickFillRequested = false,
|
||||
extraPayload,
|
||||
}: {
|
||||
clientMessageId: string;
|
||||
text: string;
|
||||
quickFillRequested?: boolean;
|
||||
extraPayload?: TExtraPayload;
|
||||
}): CreationAgentChatMessageBase & TExtraPayload {
|
||||
return {
|
||||
...(extraPayload ?? ({} as TExtraPayload)),
|
||||
clientMessageId,
|
||||
text,
|
||||
quickFillRequested,
|
||||
};
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from './creationAgentChat';
|
||||
export * from './creationAgentProgress';
|
||||
export * from './creationAgentSse';
|
||||
|
||||
Reference in New Issue
Block a user