-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathai.ts
More file actions
176 lines (156 loc) · 5.03 KB
/
Copy pathai.ts
File metadata and controls
176 lines (156 loc) · 5.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import { createTool } from "@decocms/runtime/tools";
import { z } from "zod";
import { runSQL } from "../db/postgres.ts";
import {
classifyConversation,
suggestReply,
summarizeConversation,
} from "../lib/ai.ts";
import type { Env } from "../types/env.ts";
export const classifyTool = (env: Env) =>
createTool({
id: "inbox_classify",
description:
"AI-classify a conversation's category and priority based on its messages. Requires LANGUAGE_MODEL to be configured.",
inputSchema: z.object({
conversation_id: z.string().describe("The conversation to classify"),
}),
outputSchema: z.object({
category: z.string().nullable(),
priority: z.string().nullable(),
message: z.string(),
}),
execute: async ({ context }) => {
const messages = await runSQL<{
content: string;
sender_name: string;
}>(
env,
"SELECT content, sender_name FROM inbox_message WHERE conversation_id = ? AND direction = 'inbound' ORDER BY created_at ASC LIMIT 5",
[context.conversation_id],
);
if (messages.length === 0) {
return {
category: null,
priority: null,
message: "No inbound messages to classify",
};
}
const combined = messages.map((m) => m.content).join("\n");
const customerName = messages[0].sender_name || "Unknown";
const result = await classifyConversation(env, combined, customerName);
if (!result) {
return {
category: null,
priority: null,
message:
"AI classification not available. Configure LANGUAGE_MODEL in Mesh Dashboard.",
};
}
// Update conversation
await runSQL(
env,
"UPDATE inbox_conversation SET category = ?, priority = ?, updated_at = NOW() WHERE id = ?",
[result.category, result.priority, context.conversation_id],
);
return {
category: result.category,
priority: result.priority,
message: `Classified as ${result.category} (${result.priority} priority)`,
};
},
});
export const summarizeTool = (env: Env) =>
createTool({
id: "inbox_summarize",
description:
"AI-summarize a conversation. Requires LANGUAGE_MODEL to be configured.",
inputSchema: z.object({
conversation_id: z.string().describe("The conversation to summarize"),
}),
outputSchema: z.object({
summary: z.string().nullable(),
message: z.string(),
}),
execute: async ({ context }) => {
const messages = await runSQL<{
sender_name: string;
content: string;
direction: string;
}>(
env,
"SELECT sender_name, content, direction FROM inbox_message WHERE conversation_id = ? ORDER BY created_at ASC",
[context.conversation_id],
);
if (messages.length === 0) {
return {
summary: null,
message: "No messages to summarize",
};
}
const summary = await summarizeConversation(env, messages);
if (!summary) {
return {
summary: null,
message:
"AI summarization not available. Configure LANGUAGE_MODEL in Mesh Dashboard.",
};
}
// Save summary
await runSQL(
env,
"UPDATE inbox_conversation SET ai_summary = ?, updated_at = NOW() WHERE id = ?",
[summary, context.conversation_id],
);
return { summary, message: "Summary generated" };
},
});
export const suggestReplyTool = (env: Env) =>
createTool({
id: "inbox_suggest_reply",
description:
"AI-suggest a reply for a conversation. Requires LANGUAGE_MODEL to be configured.",
inputSchema: z.object({
conversation_id: z
.string()
.describe("The conversation to suggest a reply for"),
}),
outputSchema: z.object({
suggested_reply: z.string().nullable(),
message: z.string(),
}),
execute: async ({ context }) => {
// Get conversation category
const conversations = await runSQL<{ category: string | null }>(
env,
"SELECT category FROM inbox_conversation WHERE id = ?",
[context.conversation_id],
);
const category = conversations[0]?.category ?? null;
// Get messages
const messages = await runSQL<{
sender_name: string;
content: string;
direction: string;
}>(
env,
"SELECT sender_name, content, direction FROM inbox_message WHERE conversation_id = ? ORDER BY created_at ASC",
[context.conversation_id],
);
if (messages.length === 0) {
return {
suggested_reply: null,
message: "No messages to base reply on",
};
}
const reply = await suggestReply(env, messages, category);
if (!reply) {
return {
suggested_reply: null,
message:
"AI reply suggestion not available. Configure LANGUAGE_MODEL in Mesh Dashboard.",
};
}
return { suggested_reply: reply, message: "Reply suggested" };
},
});