mcp
This commit is contained in:
@@ -109,6 +109,16 @@ export class AssistantService {
|
||||
return localResponse;
|
||||
}
|
||||
|
||||
const localMutationResponse = await this.tryHandleLocalListMutation(
|
||||
userId,
|
||||
messages,
|
||||
context,
|
||||
);
|
||||
|
||||
if (localMutationResponse) {
|
||||
return localMutationResponse;
|
||||
}
|
||||
|
||||
const response = await this.callMistralAgent(userId, messages, context);
|
||||
const content = this.extractAssistantContent(response);
|
||||
const actions = this.extractActions(response);
|
||||
@@ -176,6 +186,108 @@ export class AssistantService {
|
||||
};
|
||||
}
|
||||
|
||||
private async tryHandleLocalListMutation(
|
||||
userId: string,
|
||||
messages: AssistantChatMessage[],
|
||||
context: NormalizedAssistantPageContext | null,
|
||||
): Promise<AssistantChatResponse | null> {
|
||||
if (context?.page !== 'list_detail') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const latestUserMessage = [...messages]
|
||||
.reverse()
|
||||
.find((message) => message.role === 'user');
|
||||
const itemTitle = this.extractItemTitleToAdd(latestUserMessage?.content ?? '');
|
||||
|
||||
if (!itemTitle) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const startedAt = Date.now();
|
||||
const list = await this.listsService.addItem(userId, context.list.id, {
|
||||
title: itemTitle,
|
||||
});
|
||||
const assistantContent = `Ich habe **${itemTitle}** zu **${list.name}** hinzugefuegt.`;
|
||||
const action: AssistantAction = {
|
||||
type: 'list.item_added',
|
||||
listId: list.id,
|
||||
itemTitle,
|
||||
list,
|
||||
};
|
||||
|
||||
this.listRealtimeService.publishSnapshot(userId, list);
|
||||
|
||||
await this.recordChatLog({
|
||||
userId,
|
||||
provider: 'listify',
|
||||
endpoint: 'local:addItem',
|
||||
agentId: null,
|
||||
requestPayload: {
|
||||
intent: 'list.add_item',
|
||||
latestUserMessage: latestUserMessage?.content,
|
||||
listId: context.list.id,
|
||||
itemTitle,
|
||||
},
|
||||
responsePayload: { list },
|
||||
statusCode: 200,
|
||||
durationMs: Date.now() - startedAt,
|
||||
assistantContent,
|
||||
errorMessage: null,
|
||||
});
|
||||
|
||||
return {
|
||||
message: {
|
||||
role: 'assistant',
|
||||
content: assistantContent,
|
||||
},
|
||||
actions: [action],
|
||||
};
|
||||
}
|
||||
|
||||
private extractItemTitleToAdd(content: string): string | null {
|
||||
const compacted = content.replace(/\s+/g, ' ').trim();
|
||||
|
||||
if (!compacted) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const patterns = [
|
||||
/\b(?:fuege|füge)\s+(.+?)\s+(?:hinzu|dazu|drauf|auf die liste|auf diese liste)\b/i,
|
||||
/\b(?:schreib|schreibe|notier|notiere|pack|setze|setz)\s+(.+?)(?:\s+(?:drauf|dazu|hinzu|auf die liste|auf diese liste))?$/i,
|
||||
/\b(.+?)\s+(?:draufschreiben|aufschreiben|hinzufuegen|hinzufügen)\b/i,
|
||||
];
|
||||
|
||||
for (const pattern of patterns) {
|
||||
const match = compacted.match(pattern);
|
||||
const title = this.cleanExtractedItemTitle(match?.[1]);
|
||||
|
||||
if (title) {
|
||||
return title;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private cleanExtractedItemTitle(value: string | undefined): string | null {
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const cleaned = value
|
||||
.replace(/^(?:bitte|noch|auch|mal|hier)\s+/i, '')
|
||||
.replace(/\s+(?:bitte|noch|auch|mal)$/i, '')
|
||||
.replace(/^["'`]+|["'`.,!?]+$/g, '')
|
||||
.trim();
|
||||
|
||||
if (!cleaned || cleaned.length > 220) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return cleaned;
|
||||
}
|
||||
|
||||
private isListReadRequest(content: string): boolean {
|
||||
const asksForLists = /\b(listen|liste)\b/.test(content);
|
||||
const asksToRead =
|
||||
|
||||
Reference in New Issue
Block a user