feat(conversation): integrate ClaudeAgentServiceV2 for consulting workflow
- Switch ConversationService to use ClaudeAgentServiceV2 - Pass consultingState and deviceInfo from conversation to context - Handle state_update chunks and save updated state to database - Move dotenv to dependencies for migration runtime Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
c0a9710943
commit
9f2bdee8d9
|
|
@ -29,6 +29,7 @@
|
|||
"@nestjs/websockets": "^10.0.0",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.14.0",
|
||||
"dotenv": "^16.3.0",
|
||||
"ioredis": "^5.3.0",
|
||||
"kafkajs": "^2.2.4",
|
||||
"pg": "^8.11.0",
|
||||
|
|
@ -45,7 +46,6 @@
|
|||
"@types/node": "^20.10.0",
|
||||
"@types/socket.io": "^3.0.2",
|
||||
"@types/uuid": "^9.0.0",
|
||||
"dotenv": "^16.3.0",
|
||||
"jest": "^29.7.0",
|
||||
"ts-jest": "^29.1.0",
|
||||
"ts-node": "^10.9.0",
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ import {
|
|||
MessageType,
|
||||
} from '../domain/entities/message.entity';
|
||||
import {
|
||||
ClaudeAgentService,
|
||||
ClaudeAgentServiceV2,
|
||||
ConversationContext,
|
||||
StreamChunk,
|
||||
} from '../infrastructure/claude/claude-agent.service';
|
||||
} from '../infrastructure/claude/claude-agent-v2.service';
|
||||
|
||||
export interface CreateConversationDto {
|
||||
userId: string;
|
||||
|
|
@ -45,7 +45,7 @@ export class ConversationService {
|
|||
private conversationRepo: Repository<ConversationEntity>,
|
||||
@InjectRepository(MessageEntity)
|
||||
private messageRepo: Repository<MessageEntity>,
|
||||
private claudeAgentService: ClaudeAgentService,
|
||||
private claudeAgentService: ClaudeAgentServiceV2,
|
||||
) {}
|
||||
|
||||
/**
|
||||
|
|
@ -134,7 +134,7 @@ export class ConversationService {
|
|||
take: 20, // Last 20 messages for context
|
||||
});
|
||||
|
||||
// Build context with support for multimodal messages
|
||||
// Build context with support for multimodal messages and consulting state (V2)
|
||||
const context: ConversationContext = {
|
||||
userId: dto.userId,
|
||||
conversationId: dto.conversationId,
|
||||
|
|
@ -149,11 +149,15 @@ export class ConversationService {
|
|||
}
|
||||
return msg;
|
||||
}),
|
||||
// V2: Pass consulting state from conversation (cast through unknown for JSON/Date compatibility)
|
||||
consultingState: conversation.consultingState as unknown as ConversationContext['consultingState'],
|
||||
deviceInfo: conversation.deviceInfo,
|
||||
};
|
||||
|
||||
// Collect full response for saving
|
||||
let fullResponse = '';
|
||||
const toolCalls: Array<{ name: string; input: unknown; result: unknown }> = [];
|
||||
let updatedState: ConversationContext['consultingState'] | undefined;
|
||||
|
||||
// Stream response from Claude (with attachments for multimodal support)
|
||||
for await (const chunk of this.claudeAgentService.sendMessage(
|
||||
|
|
@ -174,11 +178,27 @@ export class ConversationService {
|
|||
if (lastToolCall) {
|
||||
lastToolCall.result = chunk.toolResult;
|
||||
}
|
||||
} else if (chunk.type === 'state_update' && chunk.newState) {
|
||||
// V2: Capture updated consulting state
|
||||
updatedState = chunk.newState;
|
||||
}
|
||||
|
||||
yield chunk;
|
||||
}
|
||||
|
||||
// V2: Save updated consulting state to conversation
|
||||
if (updatedState) {
|
||||
// Convert state to JSON-compatible format for database storage
|
||||
const stateForDb = JSON.parse(JSON.stringify(updatedState));
|
||||
await this.conversationRepo.update(conversation.id, {
|
||||
consultingState: stateForDb,
|
||||
consultingStage: updatedState.currentStageId,
|
||||
collectedInfo: stateForDb.collectedInfo,
|
||||
recommendedPrograms: updatedState.assessmentResult?.recommendedPrograms,
|
||||
conversionPath: updatedState.conversionPath,
|
||||
});
|
||||
}
|
||||
|
||||
// Save assistant response
|
||||
const assistantMessage = this.messageRepo.create({
|
||||
conversationId: dto.conversationId,
|
||||
|
|
|
|||
Loading…
Reference in New Issue