169 lines
4.7 KiB
TypeScript
169 lines
4.7 KiB
TypeScript
import type {
|
||
ConfirmCreativePuzzleTemplateRequest,
|
||
CreateCreativeAgentSessionRequest,
|
||
CreativeAgentSessionResponse,
|
||
CreativeAgentSessionSnapshot,
|
||
CreativeAgentSseEvent,
|
||
CreativeDraftEditStreamRequest,
|
||
StreamCreativeAgentMessageRequest,
|
||
} from '../../../packages/shared/src/contracts/creativeAgent';
|
||
import { parseApiErrorMessage } from '../../../packages/shared/src/http';
|
||
import type { TextStreamOptions } from '../aiTypes';
|
||
import { fetchWithApiAuth, requestJson } from '../apiClient';
|
||
import {
|
||
readCreativeAgentResultFromSse,
|
||
readCreativeAgentSessionFromSse,
|
||
} from './creativeAgentSse';
|
||
|
||
const CREATIVE_AGENT_API_BASE = '/api/runtime/creative-agent/sessions';
|
||
|
||
export type CreativeAgentStreamOptions = TextStreamOptions & {
|
||
onEvent?: (event: CreativeAgentSseEvent) => void;
|
||
};
|
||
|
||
function buildJsonPostInit(payload: unknown): RequestInit {
|
||
return {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify(payload),
|
||
};
|
||
}
|
||
|
||
async function openCreativeAgentSsePost(
|
||
url: string,
|
||
payload: unknown,
|
||
fallbackMessage: string,
|
||
signal?: AbortSignal,
|
||
) {
|
||
const response = await fetchWithApiAuth(url, {
|
||
...buildJsonPostInit(payload),
|
||
signal,
|
||
});
|
||
|
||
if (!response.ok) {
|
||
const responseText = await response.text();
|
||
throw new Error(parseApiErrorMessage(responseText, fallbackMessage));
|
||
}
|
||
|
||
if (!response.body) {
|
||
throw new Error('streaming response body is unavailable');
|
||
}
|
||
|
||
return response;
|
||
}
|
||
|
||
export async function createCreativeAgentSession(
|
||
payload: CreateCreativeAgentSessionRequest = {},
|
||
) {
|
||
return requestJson<CreativeAgentSessionResponse>(
|
||
CREATIVE_AGENT_API_BASE,
|
||
buildJsonPostInit(payload),
|
||
'创建智能创作会话失败',
|
||
{
|
||
retry: {
|
||
maxRetries: 1,
|
||
baseDelayMs: 240,
|
||
maxDelayMs: 640,
|
||
retryUnsafeMethods: true,
|
||
},
|
||
timeoutMs: 15000,
|
||
},
|
||
);
|
||
}
|
||
|
||
export async function getCreativeAgentSession(sessionId: string) {
|
||
return requestJson<CreativeAgentSessionResponse>(
|
||
`${CREATIVE_AGENT_API_BASE}/${encodeURIComponent(sessionId)}`,
|
||
{ method: 'GET' },
|
||
'读取智能创作会话失败',
|
||
);
|
||
}
|
||
|
||
export async function streamCreativeAgentMessage(
|
||
sessionId: string,
|
||
payload: StreamCreativeAgentMessageRequest,
|
||
options: CreativeAgentStreamOptions = {},
|
||
) {
|
||
const response = await openCreativeAgentSsePost(
|
||
`${CREATIVE_AGENT_API_BASE}/${encodeURIComponent(sessionId)}/messages/stream`,
|
||
payload,
|
||
'发送智能创作消息失败',
|
||
options.signal,
|
||
);
|
||
|
||
return readCreativeAgentSessionFromSse(response, {
|
||
...options,
|
||
fallbackMessage: '发送智能创作消息失败',
|
||
incompleteMessage: '智能创作消息流式结果不完整',
|
||
});
|
||
}
|
||
|
||
export async function confirmCreativePuzzleTemplate(
|
||
sessionId: string,
|
||
payload: ConfirmCreativePuzzleTemplateRequest,
|
||
) {
|
||
return requestJson<CreativeAgentSessionResponse>(
|
||
`${CREATIVE_AGENT_API_BASE}/${encodeURIComponent(sessionId)}/confirm-template`,
|
||
buildJsonPostInit(payload),
|
||
'确认拼图模板失败',
|
||
{
|
||
retry: {
|
||
maxRetries: 1,
|
||
baseDelayMs: 240,
|
||
maxDelayMs: 640,
|
||
retryUnsafeMethods: true,
|
||
},
|
||
},
|
||
);
|
||
}
|
||
|
||
export async function streamCreativeDraftEdit(
|
||
sessionId: string,
|
||
payload: CreativeDraftEditStreamRequest,
|
||
options: CreativeAgentStreamOptions = {},
|
||
) {
|
||
const response = await openCreativeAgentSsePost(
|
||
`${CREATIVE_AGENT_API_BASE}/${encodeURIComponent(sessionId)}/draft-edits/stream`,
|
||
payload,
|
||
'修改拼图草稿失败',
|
||
options.signal,
|
||
);
|
||
|
||
return requestCreativeDraftEditResultFromSse(response, options);
|
||
}
|
||
|
||
export async function cancelCreativeAgentSession(sessionId: string) {
|
||
return requestJson<CreativeAgentSessionResponse>(
|
||
`${CREATIVE_AGENT_API_BASE}/${encodeURIComponent(sessionId)}/cancel`,
|
||
buildJsonPostInit({}),
|
||
'取消智能创作会话失败',
|
||
);
|
||
}
|
||
|
||
async function requestCreativeDraftEditResultFromSse(
|
||
response: Response,
|
||
options: CreativeAgentStreamOptions,
|
||
) {
|
||
const result = await readCreativeAgentResultFromSse(response, {
|
||
...options,
|
||
fallbackMessage: '修改拼图草稿失败',
|
||
incompleteMessage: '智能创作修改结果不完整',
|
||
});
|
||
|
||
if (result.draftEditResult) {
|
||
return result.draftEditResult;
|
||
}
|
||
|
||
// 中文注释:后端如果暂时只返回 session,调用方仍能用 session 做保底收尾。
|
||
return result.session as CreativeAgentSessionSnapshot;
|
||
}
|
||
|
||
export const creativeAgentClient = {
|
||
createSession: createCreativeAgentSession,
|
||
getSession: getCreativeAgentSession,
|
||
streamMessage: streamCreativeAgentMessage,
|
||
confirmTemplate: confirmCreativePuzzleTemplate,
|
||
streamDraftEdit: streamCreativeDraftEdit,
|
||
cancelSession: cancelCreativeAgentSession,
|
||
};
|