feat: update codex live runtime and restart flow

This commit is contained in:
2026-04-23 18:10:43 +09:00
parent b0b9980a6c
commit 6e863feafd
36 changed files with 1636 additions and 358 deletions

View File

@@ -7,6 +7,7 @@ import { z } from 'zod';
import { env } from '../config/env.js';
import { hasErrorLogViewAccessToken } from '../services/error-log-service.js';
import { getActiveChatService, getChatRuntimeController } from '../services/chat-service.js';
import { rollbackChatRuntimeRequest } from '../services/chat-runtime-rollback-service.js';
import {
createChatConversation,
deleteUnansweredChatConversationRequest,
@@ -16,6 +17,7 @@ import {
listChatConversationDetailPage,
listChatConversations,
markChatConversationResponsesRead,
upsertChatConversationRequest,
updateChatConversationContext,
} from '../services/chat-room-service.js';
import { chatRuntimeService } from '../services/chat-runtime-service.js';
@@ -308,11 +310,56 @@ export async function registerChatRoutes(app: FastifyInstance) {
};
});
app.post('/api/chat/runtime/jobs/:requestId/rollback', async (request, reply) => {
const params = z.object({
requestId: z.string().trim().min(1).max(120),
}).parse(request.params ?? {});
const payload = z
.object({
sessionId: z.string().trim().min(1).max(120).optional(),
})
.parse(request.body ?? {});
chatRuntimeService.appendLog(params.requestId, '사용자 요청으로 최근 실행 롤백을 시작합니다.');
try {
const result = await rollbackChatRuntimeRequest({
requestId: params.requestId,
sessionId: payload.sessionId,
});
await upsertChatConversationRequest(result.sessionId, {
requestId: result.requestId,
status: 'cancelled',
statusMessage: '사용자 요청으로 최근 실행 변경을 롤백했습니다.',
});
chatRuntimeService.setArchivedJobTerminalStatus(
params.requestId,
'cancelled',
'최근 실행이 롤백되어 상태를 취소로 변경했습니다.',
);
chatRuntimeService.appendLog(params.requestId, '최근 실행 롤백이 완료되었습니다.');
return {
ok: true,
...result,
};
} catch (error) {
const message = error instanceof Error ? error.message : '최근 실행 롤백에 실패했습니다.';
chatRuntimeService.appendLog(params.requestId, `최근 실행 롤백 실패: ${message}`);
return reply.code(409).send({
message,
});
}
});
app.post('/api/chat/conversations', async (request) => {
const payload = z.object({
sessionId: z.string().trim().min(1).max(120),
title: z.string().trim().max(200).optional(),
chatTypeId: z.string().trim().max(120).nullable().optional(),
lastChatTypeId: z.string().trim().max(120).nullable().optional(),
contextLabel: z.string().trim().max(200).optional(),
contextDescription: z.string().trim().max(2000).optional(),
notifyOffline: z.boolean().optional(),
@@ -324,6 +371,7 @@ export async function registerChatRoutes(app: FastifyInstance) {
clientId: clientId || null,
title: payload.title ?? '새 대화',
chatTypeId: payload.chatTypeId ?? null,
lastChatTypeId: payload.lastChatTypeId ?? payload.chatTypeId ?? null,
contextLabel: payload.contextLabel ?? null,
contextDescription: payload.contextDescription ?? null,
notifyOffline: payload.notifyOffline ?? true,
@@ -438,6 +486,7 @@ export async function registerChatRoutes(app: FastifyInstance) {
const payload = z.object({
title: z.string().trim().min(1).max(200).optional(),
chatTypeId: z.string().trim().max(120).optional().nullable(),
lastChatTypeId: z.string().trim().max(120).optional().nullable(),
contextLabel: z.string().trim().max(200).optional().nullable(),
contextDescription: z.string().trim().max(2000).optional().nullable(),
notifyOffline: z.boolean().optional(),
@@ -456,6 +505,7 @@ export async function registerChatRoutes(app: FastifyInstance) {
title: payload.title ?? current.title,
clientId: current.clientId,
chatTypeId: payload.chatTypeId ?? current.chatTypeId,
lastChatTypeId: payload.lastChatTypeId ?? current.lastChatTypeId ?? current.chatTypeId,
contextLabel: payload.contextLabel ?? current.contextLabel,
contextDescription: payload.contextDescription ?? current.contextDescription,
notifyOffline: payload.notifyOffline ?? current.notifyOffline,