This commit is contained in:
118
src/components/rpg-entry/useRpgCreationAgentOperationPolling.ts
Normal file
118
src/components/rpg-entry/useRpgCreationAgentOperationPolling.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import type {
|
||||
CustomWorldAgentOperationRecord,
|
||||
CustomWorldAgentSessionSnapshot,
|
||||
} from '../../../packages/shared/src/contracts/customWorldAgent';
|
||||
import {
|
||||
getRpgCreationOperation,
|
||||
} from '../../services/rpg-creation';
|
||||
import {
|
||||
createFailedAgentOperation,
|
||||
resolveRpgCreationErrorMessage,
|
||||
} from './rpgEntryShared';
|
||||
|
||||
type UseRpgCreationAgentOperationPollingParams = {
|
||||
activeAgentSessionId: string | null;
|
||||
activeAgentOperationId: string | null;
|
||||
userId: string | null | undefined;
|
||||
setAgentOperation: (
|
||||
operation: CustomWorldAgentOperationRecord | null,
|
||||
) => void;
|
||||
persistAgentUiState: (
|
||||
sessionId: string | null,
|
||||
operationId: string | null,
|
||||
generationSource?: 'agent-draft-foundation' | null,
|
||||
) => void;
|
||||
syncAgentSessionSnapshot: (
|
||||
sessionId: string,
|
||||
) => Promise<CustomWorldAgentSessionSnapshot | null>;
|
||||
};
|
||||
|
||||
/**
|
||||
* 只负责当前 Agent operation 的轮询与完成态刷新。
|
||||
* 壳层不再直接维护轮询 interval 与失败兜底细节。
|
||||
*/
|
||||
export function useRpgCreationAgentOperationPolling(
|
||||
params: UseRpgCreationAgentOperationPollingParams,
|
||||
) {
|
||||
const {
|
||||
activeAgentSessionId,
|
||||
activeAgentOperationId,
|
||||
userId,
|
||||
setAgentOperation,
|
||||
persistAgentUiState,
|
||||
syncAgentSessionSnapshot,
|
||||
} = params;
|
||||
|
||||
useEffect(() => {
|
||||
if (!activeAgentSessionId || !activeAgentOperationId || !userId) {
|
||||
return;
|
||||
}
|
||||
|
||||
let cancelled = false;
|
||||
|
||||
const pollOperation = async () => {
|
||||
try {
|
||||
const nextOperation = await getRpgCreationOperation(
|
||||
activeAgentSessionId,
|
||||
activeAgentOperationId,
|
||||
);
|
||||
|
||||
if (cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
setAgentOperation(nextOperation);
|
||||
|
||||
if (
|
||||
nextOperation.status === 'completed' ||
|
||||
nextOperation.status === 'failed'
|
||||
) {
|
||||
persistAgentUiState(
|
||||
activeAgentSessionId,
|
||||
nextOperation.type === 'draft_foundation'
|
||||
? activeAgentOperationId
|
||||
: null,
|
||||
nextOperation.type === 'draft_foundation'
|
||||
? 'agent-draft-foundation'
|
||||
: null,
|
||||
);
|
||||
await syncAgentSessionSnapshot(activeAgentSessionId).catch(
|
||||
() => null,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
if (cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
setAgentOperation(
|
||||
createFailedAgentOperation({
|
||||
type: 'process_message',
|
||||
phaseLabel: '读取操作状态失败',
|
||||
error: resolveRpgCreationErrorMessage(error, '读取共创操作状态失败。'),
|
||||
}),
|
||||
);
|
||||
persistAgentUiState(activeAgentSessionId, null);
|
||||
}
|
||||
};
|
||||
|
||||
void pollOperation();
|
||||
const intervalId = window.setInterval(() => {
|
||||
void pollOperation();
|
||||
}, 1200);
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
window.clearInterval(intervalId);
|
||||
};
|
||||
}, [
|
||||
activeAgentOperationId,
|
||||
activeAgentSessionId,
|
||||
persistAgentUiState,
|
||||
setAgentOperation,
|
||||
syncAgentSessionSnapshot,
|
||||
userId,
|
||||
]);
|
||||
}
|
||||
Reference in New Issue
Block a user