feat: implement processDomainConsultation main handler
- Add full conversation flow with session management - Handle tool call execution - Support __PASSTHROUGH__ and __SESSION_END__ markers - Add hasDomainSession helper for routing - Export executeDomainAction from domain-tool.ts Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -593,10 +593,93 @@ export async function processDomainConsultation(
|
||||
userMessage: string,
|
||||
env: Env
|
||||
): Promise<string> {
|
||||
// TODO: Implement in Task 8
|
||||
logger.info('도메인 상담 처리 요청 (미구현)', {
|
||||
userId,
|
||||
message: userMessage.slice(0, 50),
|
||||
});
|
||||
return '__PASSTHROUGH__';
|
||||
const startTime = Date.now();
|
||||
logger.info('도메인 상담 시작', { userId, message: userMessage.substring(0, 100) });
|
||||
|
||||
try {
|
||||
// 1. Check for existing session
|
||||
let session = await getDomainSession(db, userId);
|
||||
|
||||
// 2. Create new session if none exists and message seems domain-related
|
||||
// (For first call, we always try to process - AI will return __PASSTHROUGH__ if not relevant)
|
||||
if (!session) {
|
||||
session = createDomainSession(userId, 'gathering');
|
||||
}
|
||||
|
||||
// 3. Add user message to session
|
||||
addMessageToSession(session, 'user', userMessage);
|
||||
|
||||
// 4. Call AI to get response and possible tool calls
|
||||
const aiResult = await callDomainExpertAI(session, userMessage, env);
|
||||
|
||||
// 5. Handle __PASSTHROUGH__ - not domain related
|
||||
if (aiResult.response === '__PASSTHROUGH__' || aiResult.response.includes('__PASSTHROUGH__')) {
|
||||
logger.info('도메인 상담 패스스루', { userId });
|
||||
// Don't save session if passthrough
|
||||
return '__PASSTHROUGH__';
|
||||
}
|
||||
|
||||
// 6. Execute tool calls if any
|
||||
let toolResults: string[] = [];
|
||||
if (aiResult.toolCalls && aiResult.toolCalls.length > 0) {
|
||||
for (const toolCall of aiResult.toolCalls) {
|
||||
const result = await executeDomainToolCall(
|
||||
toolCall.name,
|
||||
toolCall.arguments,
|
||||
env,
|
||||
userId,
|
||||
db
|
||||
);
|
||||
toolResults.push(result);
|
||||
}
|
||||
}
|
||||
|
||||
// 7. Build final response
|
||||
let finalResponse = aiResult.response;
|
||||
if (toolResults.length > 0) {
|
||||
// If we have tool results, include them in the response
|
||||
// The AI response might be a summary, but tool results have the actual data
|
||||
finalResponse = toolResults.join('\n\n');
|
||||
if (aiResult.response && !aiResult.response.includes('__SESSION_END__')) {
|
||||
finalResponse = aiResult.response + '\n\n' + finalResponse;
|
||||
}
|
||||
}
|
||||
|
||||
// 8. Handle __SESSION_END__ - session complete
|
||||
if (finalResponse.includes('__SESSION_END__')) {
|
||||
logger.info('도메인 상담 세션 종료', { userId });
|
||||
await deleteDomainSession(db, userId);
|
||||
finalResponse = finalResponse.replace('__SESSION_END__', '').trim();
|
||||
return finalResponse;
|
||||
}
|
||||
|
||||
// 9. Add assistant response to session and save
|
||||
addMessageToSession(session, 'assistant', finalResponse);
|
||||
session.updated_at = Date.now();
|
||||
await saveDomainSession(db, session);
|
||||
|
||||
logger.info('도메인 상담 완료', {
|
||||
userId,
|
||||
duration: Date.now() - startTime,
|
||||
hasToolCalls: aiResult.toolCalls?.length || 0
|
||||
});
|
||||
|
||||
return finalResponse;
|
||||
|
||||
} catch (error) {
|
||||
logger.error('도메인 상담 오류', error as Error, { userId });
|
||||
return '죄송합니다. 도메인 상담 중 오류가 발생했습니다. 잠시 후 다시 시도해주세요.';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 도메인 세션 존재 여부 확인 (라우팅용)
|
||||
*
|
||||
* @param db - D1 Database
|
||||
* @param userId - Telegram User ID
|
||||
* @returns true if active session exists, false otherwise
|
||||
*/
|
||||
export async function hasDomainSession(db: D1Database, userId: string): Promise<boolean> {
|
||||
const session = await getDomainSession(db, userId);
|
||||
return session !== null && !isSessionExpired(session);
|
||||
}
|
||||
|
||||
@@ -470,7 +470,7 @@ async function callNamecheapApi(
|
||||
}
|
||||
|
||||
// 도메인 작업 직접 실행 (Agent 없이 코드로 처리)
|
||||
async function executeDomainAction(
|
||||
export async function executeDomainAction(
|
||||
action: string,
|
||||
args: { domain?: string; nameservers?: string[]; tld?: string },
|
||||
allowedDomains: string[],
|
||||
|
||||
Reference in New Issue
Block a user