feat: complete agent refactoring integration

- Add deposit session routing to openai-service.ts
- Convert deposit-tool to agent trigger (delegate to deposit-agent)
- Update CLAUDE.md with new agent architecture

Changes:
- openai-service.ts: Import and check hasDepositSession, route to processDepositConsultation
- deposit-tool.ts: Convert action → natural language → delegate to Deposit Agent
- CLAUDE.md: Update Core Services, Function Calling Tools, Data Layer, Deposit System sections

All tests passing (192/195), dev server starts successfully.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
kappa
2026-02-05 10:30:20 +09:00
parent f5c38ad909
commit 2bd9bc4c2b
3 changed files with 115 additions and 72 deletions

View File

@@ -9,6 +9,7 @@ import { ERROR_MESSAGES } from './constants/messages';
import { getServerSession, processServerConsultation } from './agents/server-agent';
import { getTroubleshootSession, processTroubleshoot } from './agents/troubleshoot-agent';
import { processDomainConsultation, hasDomainSession } from './agents/domain-agent';
import { processDepositConsultation, hasDepositSession } from './agents/deposit-agent';
import { sendMessage } from './telegram';
const logger = createLogger('openai');
@@ -287,6 +288,29 @@ export async function generateOpenAIResponse(
});
// Continue with normal flow if session check fails
}
// Check for active deposit session
try {
const hasDepositSess = await hasDepositSession(env.DB, telegramUserId);
if (hasDepositSess) {
logger.info('예치금 세션 감지, 예치금 에이전트로 라우팅', {
userId: telegramUserId
});
const depositResponse = await processDepositConsultation(env.DB, telegramUserId, userMessage, env);
// PASSTHROUGH: 무관한 메시지는 일반 처리로 전환
if (depositResponse !== '__PASSTHROUGH__') {
return depositResponse;
}
// Continue to normal flow below
}
} catch (error) {
logger.error('Deposit session check failed, continuing with normal flow', error as Error, {
telegramUserId
});
// Continue with normal flow if session check fails
}
}
if (!env.OPENAI_API_KEY) {

View File

@@ -1,4 +1,4 @@
import { executeDepositFunction, type DepositContext } from '../agents/deposit-agent';
import { processDepositConsultation } from '../agents/deposit-agent';
import type {
Env,
DepositFunctionResult,
@@ -159,61 +159,58 @@ export async function executeManageDeposit(
const { action, depositor_name, amount, transaction_id, limit } = args;
logger.info('시작', { action, depositor_name, amount, userId: maskUserId(telegramUserId) });
if (!telegramUserId || !db) {
if (!telegramUserId || !db || !env) {
return '🚫 예치금 기능을 사용할 수 없습니다.';
}
// 사용자 조회
const user = await db.prepare(
'SELECT id FROM users WHERE telegram_id = ?'
).bind(telegramUserId).first<{ id: number }>();
// Convert action to natural message and delegate to deposit agent
const userMessage = buildDepositMessage(args);
if (!user) {
return '🚫 사용자 정보를 찾을 수 없습니다.';
logger.info('예치금 에이전트로 위임', { userMessage, userId: maskUserId(telegramUserId) });
// Delegate to deposit agent
const response = await processDepositConsultation(db, telegramUserId, userMessage, env);
if (response === '__PASSTHROUGH__') {
return '예치금 관련 요청을 이해하지 못했습니다.';
}
const isAdmin = telegramUserId === env?.DEPOSIT_ADMIN_ID;
const context: DepositContext = {
userId: user.id,
telegramUserId,
isAdmin,
db,
};
return response;
}
// action → executeDepositFunction 매핑
const actionMap: Record<string, string> = {
balance: 'get_balance',
account: 'get_account_info',
request: 'request_deposit',
history: 'get_transactions',
cancel: 'cancel_transaction',
pending: 'get_pending_list',
confirm: 'confirm_deposit',
reject: 'reject_deposit',
};
const funcName = actionMap[action];
if (!funcName) {
return `🚫 알 수 없는 작업: ${action}`;
}
try {
const funcArgs: ManageDepositArgs = {
action: action as ManageDepositArgs['action']
};
if (depositor_name) funcArgs.depositor_name = depositor_name;
if (amount) funcArgs.amount = Number(amount);
if (transaction_id) funcArgs.transaction_id = Number(transaction_id);
if (limit) funcArgs.limit = Number(limit);
logger.info('executeDepositFunction 호출', { funcName, funcArgs });
const result = await executeDepositFunction(funcName, funcArgs, context);
logger.info('결과', { result: JSON.stringify(result).slice(0, LOG_RESULT_MAX_LENGTH) });
// 결과 포맷팅 (고정 형식)
return formatDepositResult(action, result);
} catch (error) {
logger.error('예치금 처리 오류', error as Error);
return '🚫 예치금 처리 중 오류가 발생했습니다. 잠시 후 다시 시도해주세요.';
/**
* Convert manage_deposit tool arguments to natural language message for deposit agent
*/
function buildDepositMessage(args: {
action: string;
depositor_name?: string;
amount?: number;
transaction_id?: number;
limit?: number
}): string {
switch (args.action) {
case 'balance':
return '잔액 확인해줘';
case 'account':
return '입금 계좌 알려줘';
case 'request':
if (args.amount && args.depositor_name) {
return `${args.depositor_name} ${args.amount}원 입금했어`;
} else if (args.amount) {
return `${args.amount}원 입금할게`;
}
return '입금 신고할게';
case 'history':
return args.limit ? `거래 내역 ${args.limit}개 보여줘` : '거래 내역 보여줘';
case 'cancel':
return args.transaction_id ? `거래 ${args.transaction_id} 취소해줘` : '입금 취소할게';
case 'pending':
return '대기 중인 입금 목록 보여줘';
case 'confirm':
return args.transaction_id ? `거래 ${args.transaction_id} 승인해줘` : '입금 승인할게';
case 'reject':
return args.transaction_id ? `거래 ${args.transaction_id} 거절해줘` : '입금 거절할게';
default:
return `예치금 ${args.action}`;
}
}