feat: add wooden fish play template
This commit is contained in:
274
src/services/wooden-fish/woodenFishClient.ts
Normal file
274
src/services/wooden-fish/woodenFishClient.ts
Normal file
@@ -0,0 +1,274 @@
|
||||
import type {
|
||||
WoodenFishActionRequest,
|
||||
WoodenFishActionResponse,
|
||||
WoodenFishCheckpointRunRequest,
|
||||
WoodenFishFinishRunRequest,
|
||||
WoodenFishGalleryCardResponse,
|
||||
WoodenFishGalleryDetailResponse,
|
||||
WoodenFishGalleryResponse,
|
||||
WoodenFishRunResponse,
|
||||
WoodenFishRuntimeRunSnapshotResponse,
|
||||
WoodenFishSessionResponse,
|
||||
WoodenFishSessionSnapshotResponse,
|
||||
WoodenFishWorkDetailResponse,
|
||||
WoodenFishWorkMutationResponse,
|
||||
WoodenFishWorkProfileResponse,
|
||||
WoodenFishWorkspaceCreateRequest,
|
||||
WoodenFishWorkSummaryResponse,
|
||||
} from '../../../packages/shared/src/contracts/woodenFish';
|
||||
import { type ApiRetryOptions, requestJson } from '../apiClient';
|
||||
import { createCreationAgentClient } from '../creation-agent';
|
||||
|
||||
const WOODEN_FISH_API_BASE = '/api/creation/wooden-fish/sessions';
|
||||
const WOODEN_FISH_WORKS_API_BASE = '/api/creation/wooden-fish/works';
|
||||
const WOODEN_FISH_RUNTIME_API_BASE = '/api/runtime/wooden-fish';
|
||||
const WOODEN_FISH_RUNTIME_READ_RETRY: ApiRetryOptions = {
|
||||
maxRetries: 1,
|
||||
baseDelayMs: 120,
|
||||
maxDelayMs: 360,
|
||||
};
|
||||
|
||||
export type {
|
||||
WoodenFishActionRequest,
|
||||
WoodenFishActionResponse,
|
||||
WoodenFishCheckpointRunRequest,
|
||||
WoodenFishFinishRunRequest,
|
||||
WoodenFishGalleryCardResponse,
|
||||
WoodenFishGalleryDetailResponse,
|
||||
WoodenFishGalleryResponse,
|
||||
WoodenFishRunResponse,
|
||||
WoodenFishRuntimeRunSnapshotResponse,
|
||||
WoodenFishSessionResponse,
|
||||
WoodenFishSessionSnapshotResponse,
|
||||
WoodenFishWorkDetailResponse,
|
||||
WoodenFishWorkMutationResponse,
|
||||
WoodenFishWorkProfileResponse,
|
||||
WoodenFishWorkspaceCreateRequest,
|
||||
};
|
||||
export type CreateWoodenFishSessionRequest = WoodenFishWorkspaceCreateRequest;
|
||||
export type WoodenFishSessionSnapshot = WoodenFishSessionSnapshotResponse;
|
||||
|
||||
const woodenFishCreationClient = createCreationAgentClient<
|
||||
WoodenFishWorkspaceCreateRequest,
|
||||
WoodenFishSessionResponse,
|
||||
WoodenFishSessionResponse,
|
||||
WoodenFishSessionSnapshotResponse,
|
||||
never,
|
||||
never,
|
||||
WoodenFishActionRequest,
|
||||
WoodenFishActionResponse
|
||||
>({
|
||||
apiBase: WOODEN_FISH_API_BASE,
|
||||
messages: {
|
||||
createSession: '创建敲木鱼共创会话失败',
|
||||
getSession: '读取敲木鱼共创会话失败',
|
||||
sendMessage: '发送敲木鱼共创消息失败',
|
||||
streamIncomplete: '敲木鱼共创消息流式结果不完整',
|
||||
executeAction: '执行敲木鱼共创操作失败',
|
||||
},
|
||||
});
|
||||
|
||||
type FlattenedWoodenFishWorkProfileResponse = Omit<
|
||||
WoodenFishWorkProfileResponse,
|
||||
'summary'
|
||||
> &
|
||||
WoodenFishWorkSummaryResponse;
|
||||
|
||||
function normalizeWoodenFishWorkProfile(
|
||||
work:
|
||||
| WoodenFishWorkProfileResponse
|
||||
| FlattenedWoodenFishWorkProfileResponse,
|
||||
): WoodenFishWorkProfileResponse {
|
||||
if ('summary' in work && work.summary) {
|
||||
return work;
|
||||
}
|
||||
|
||||
const flattened = work as FlattenedWoodenFishWorkProfileResponse;
|
||||
const summary: WoodenFishWorkProfileResponse['summary'] = {
|
||||
runtimeKind: flattened.runtimeKind,
|
||||
workId: flattened.workId,
|
||||
profileId: flattened.profileId,
|
||||
ownerUserId: flattened.ownerUserId,
|
||||
sourceSessionId: flattened.sourceSessionId ?? null,
|
||||
workTitle: flattened.workTitle,
|
||||
workDescription: flattened.workDescription,
|
||||
themeTags: flattened.themeTags,
|
||||
coverImageSrc: flattened.coverImageSrc ?? null,
|
||||
publicationStatus: flattened.publicationStatus,
|
||||
playCount: flattened.playCount,
|
||||
updatedAt: flattened.updatedAt,
|
||||
publishedAt: flattened.publishedAt ?? null,
|
||||
publishReady: flattened.publishReady,
|
||||
generationStatus: flattened.generationStatus,
|
||||
};
|
||||
|
||||
return {
|
||||
summary,
|
||||
draft: flattened.draft,
|
||||
hitObjectAsset: flattened.hitObjectAsset,
|
||||
hitSoundAsset: flattened.hitSoundAsset,
|
||||
floatingWords: flattened.floatingWords,
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeWoodenFishActionResponse(
|
||||
response: WoodenFishActionResponse,
|
||||
): WoodenFishActionResponse {
|
||||
return {
|
||||
...response,
|
||||
work: response.work ? normalizeWoodenFishWorkProfile(response.work) : null,
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeWoodenFishWorkDetailResponse(
|
||||
response: WoodenFishWorkDetailResponse,
|
||||
): WoodenFishWorkDetailResponse {
|
||||
return {
|
||||
...response,
|
||||
item: normalizeWoodenFishWorkProfile(response.item),
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeWoodenFishWorkMutationResponse(
|
||||
response: WoodenFishWorkMutationResponse,
|
||||
): WoodenFishWorkMutationResponse {
|
||||
return {
|
||||
...response,
|
||||
item: normalizeWoodenFishWorkProfile(response.item),
|
||||
};
|
||||
}
|
||||
|
||||
export function createWoodenFishCreationSession(
|
||||
payload: WoodenFishWorkspaceCreateRequest,
|
||||
) {
|
||||
return woodenFishCreationClient.createSession(payload);
|
||||
}
|
||||
|
||||
export function getWoodenFishCreationSession(sessionId: string) {
|
||||
return woodenFishCreationClient.getSession(sessionId);
|
||||
}
|
||||
|
||||
export function executeWoodenFishCreationAction(
|
||||
sessionId: string,
|
||||
payload: WoodenFishActionRequest,
|
||||
) {
|
||||
return woodenFishCreationClient
|
||||
.executeAction(sessionId, payload)
|
||||
.then(normalizeWoodenFishActionResponse);
|
||||
}
|
||||
|
||||
export async function getWoodenFishWorkDetail(profileId: string) {
|
||||
const response = await requestJson<WoodenFishWorkDetailResponse>(
|
||||
`${WOODEN_FISH_RUNTIME_API_BASE}/works/${encodeURIComponent(profileId)}`,
|
||||
{ method: 'GET' },
|
||||
'读取敲木鱼作品详情失败',
|
||||
);
|
||||
return normalizeWoodenFishWorkDetailResponse(response);
|
||||
}
|
||||
|
||||
export async function listWoodenFishGallery() {
|
||||
return requestJson<WoodenFishGalleryResponse>(
|
||||
`${WOODEN_FISH_RUNTIME_API_BASE}/gallery`,
|
||||
{ method: 'GET' },
|
||||
'读取敲木鱼广场失败',
|
||||
{
|
||||
retry: WOODEN_FISH_RUNTIME_READ_RETRY,
|
||||
skipAuth: true,
|
||||
skipRefresh: true,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export async function getWoodenFishGalleryDetail(publicWorkCode: string) {
|
||||
const response = await requestJson<WoodenFishGalleryDetailResponse>(
|
||||
`${WOODEN_FISH_RUNTIME_API_BASE}/gallery/${encodeURIComponent(publicWorkCode)}`,
|
||||
{ method: 'GET' },
|
||||
'读取敲木鱼广场详情失败',
|
||||
{
|
||||
retry: WOODEN_FISH_RUNTIME_READ_RETRY,
|
||||
skipAuth: true,
|
||||
skipRefresh: true,
|
||||
},
|
||||
);
|
||||
return normalizeWoodenFishWorkDetailResponse(response);
|
||||
}
|
||||
|
||||
export async function publishWoodenFishWork(profileId: string) {
|
||||
const response = await requestJson<WoodenFishWorkMutationResponse>(
|
||||
`${WOODEN_FISH_WORKS_API_BASE}/${encodeURIComponent(profileId)}/publish`,
|
||||
{ method: 'POST' },
|
||||
'发布敲木鱼作品失败',
|
||||
);
|
||||
return normalizeWoodenFishWorkMutationResponse(response);
|
||||
}
|
||||
|
||||
export async function startWoodenFishRuntimeRun(profileId: string) {
|
||||
return requestJson<WoodenFishRunResponse>(
|
||||
`${WOODEN_FISH_RUNTIME_API_BASE}/runs`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ profileId }),
|
||||
},
|
||||
'启动敲木鱼运行态失败',
|
||||
);
|
||||
}
|
||||
|
||||
export async function checkpointWoodenFishRun(
|
||||
runId: string,
|
||||
payload: Omit<WoodenFishCheckpointRunRequest, 'clientEventId'>,
|
||||
) {
|
||||
const requestPayload: WoodenFishCheckpointRunRequest = {
|
||||
...payload,
|
||||
clientEventId: `checkpoint-${runId}-${Date.now()}`,
|
||||
};
|
||||
|
||||
return requestJson<WoodenFishRunResponse>(
|
||||
`${WOODEN_FISH_RUNTIME_API_BASE}/runs/${encodeURIComponent(runId)}/checkpoint`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(requestPayload),
|
||||
},
|
||||
'保存敲木鱼进度失败',
|
||||
);
|
||||
}
|
||||
|
||||
export async function finishWoodenFishRun(
|
||||
runId: string,
|
||||
payload: Omit<WoodenFishFinishRunRequest, 'clientEventId'>,
|
||||
) {
|
||||
const requestPayload: WoodenFishFinishRunRequest = {
|
||||
...payload,
|
||||
clientEventId: `finish-${runId}-${Date.now()}`,
|
||||
};
|
||||
|
||||
return requestJson<WoodenFishRunResponse>(
|
||||
`${WOODEN_FISH_RUNTIME_API_BASE}/runs/${encodeURIComponent(runId)}/finish`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(requestPayload),
|
||||
},
|
||||
'结束敲木鱼运行失败',
|
||||
);
|
||||
}
|
||||
|
||||
export const woodenFishClient = {
|
||||
checkpointRun: checkpointWoodenFishRun,
|
||||
createSession: createWoodenFishCreationSession,
|
||||
executeAction: executeWoodenFishCreationAction,
|
||||
finishRun: finishWoodenFishRun,
|
||||
getGalleryDetail: getWoodenFishGalleryDetail,
|
||||
getSession: getWoodenFishCreationSession,
|
||||
getWorkDetail: getWoodenFishWorkDetail,
|
||||
listGallery: listWoodenFishGallery,
|
||||
publishWork: publishWoodenFishWork,
|
||||
startRun: startWoodenFishRuntimeRun,
|
||||
};
|
||||
Reference in New Issue
Block a user