返回 presentation-ai
processPastedContent.ts
根目录 / src / ai / lib / processPastedContent.ts
1 import { HumanMessage, type BaseMessage } from "@langchain/core/messages";
2 import { createMiddleware } from "langchain";
3
4 interface PastedContentItem {
5 id: string;
6 content: string;
7 startIndex: number;
8 }
9
10 function buildEnhancedContent(
11 originalContent: string,
12 pastedContent: PastedContentItem[],
13 ): string {
14 const sorted = [...pastedContent].sort((a, b) => b.startIndex - a.startIndex);
15
16 let result = originalContent;
17
18 for (const item of sorted) {
19 const insertPosition = Math.min(item.startIndex, result.length);
20 const pastedTag = `\n${item.content}\n`;
21
22 result =
23 result.slice(0, insertPosition) +
24 pastedTag +
25 result.slice(insertPosition);
26 }
27
28 return result;
29 }
30
31 export const pastedContentMiddleware = createMiddleware({
32 name: "ProcessPastedContent",
33 wrapModelCall: async (request, handler) => {
34 const processedMessages = request.messages.map((message) => {
35 if (message.type !== "human") {
36 return message;
37 }
38
39 const pastedContent = message.additional_kwargs?.pastedContent as
40 | PastedContentItem[]
41 | undefined;
42
43 if (!pastedContent || pastedContent.length === 0) {
44 return message;
45 }
46
47 const originalContent =
48 typeof message.content === "string"
49 ? message.content
50 : Array.isArray(message.content)
51 ? message.content
52 .filter((part) => typeof part === "object" && part.type === "text")
53 .map((part) => ("text" in part ? part.text ?? "" : ""))
54 .join("\n")
55 : "";
56
57 return new HumanMessage({
58 content: buildEnhancedContent(originalContent, pastedContent),
59 id: message.id,
60 response_metadata: message.response_metadata,
61 additional_kwargs: {
62 ...message.additional_kwargs,
63 pastedContentProcessed: true,
64 },
65 });
66 });
67
68 return handler({
69 ...request,
70 messages: processedMessages,
71 });
72 },
73 });
74
75 export function processPastedContent(messages: BaseMessage[]): BaseMessage[] {
76 return messages.map((message) => {
77 if (message.type !== "human") {
78 return message;
79 }
80
81 const pastedContent = message.additional_kwargs?.pastedContent as
82 | PastedContentItem[]
83 | undefined;
84
85 if (!pastedContent || pastedContent.length === 0) {
86 return message;
87 }
88
89 const originalContent =
90 typeof message.content === "string"
91 ? message.content
92 : Array.isArray(message.content)
93 ? message.content
94 .filter((part) => typeof part === "object" && part.type === "text")
95 .map((part) => ("text" in part ? part.text ?? "" : ""))
96 .join("\n")
97 : "";
98
99 return new HumanMessage({
100 content: buildEnhancedContent(originalContent, pastedContent),
101 id: message.id,
102 response_metadata: message.response_metadata,
103 additional_kwargs: {
104 ...message.additional_kwargs,
105 pastedContentProcessed: true,
106 },
107 });
108 });
109 }
110
110 lines TYPESCRIPT