Skip to content

Commit e2d53c4

Browse files
committed
feat: simplify ai usage
1 parent b645fde commit e2d53c4

5 files changed

Lines changed: 26 additions & 236 deletions

File tree

app/_lib/_agent/agent.ts

Lines changed: 14 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,6 @@
11
import { getLastWeekLeaderboard, getLastWeekTransactions, getTodayLeaderboard } from "../_db/index";
22
import { ChatCompletionCreateParams, createChatCompletion } from "../_openai/client";
33

4-
interface UserInput {
5-
tools: string;
6-
prompt: string;
7-
}
8-
9-
interface ToolCall {
10-
toolName: string;
11-
args: Record<string, unknown>;
12-
}
13-
144
interface Leaderboard {
155
toRealName: string;
166
totalReceived: number;
@@ -32,78 +22,8 @@ interface ToolResults {
3222
getTodayLeaderboard?: Leaderboard[];
3323
}
3424

35-
async function callModelWithTools(
36-
userInput: UserInput
37-
): Promise<ToolCall[] | null> {
38-
const params: ChatCompletionCreateParams = {
39-
model: "gpt-4.1-mini",
40-
messages: [
41-
{
42-
role: "system",
43-
content: "You are an assistant that decides which tools to call based on user input."
44-
},
45-
{
46-
role: "user",
47-
content: JSON.stringify(userInput)
48-
}
49-
],
50-
tools: [
51-
{
52-
type: "function",
53-
function: {
54-
name: "getLastWeekLeaderboard",
55-
description: "Get the leaderboard for the last week",
56-
parameters: {
57-
type: "object",
58-
properties: {},
59-
required: []
60-
}
61-
}
62-
},
63-
{
64-
type: "function",
65-
function: {
66-
name: "getLastWeekTransactions",
67-
description: "Get all transactions from the last week",
68-
parameters: {
69-
type: "object",
70-
properties: {},
71-
required: []
72-
}
73-
}
74-
},
75-
{
76-
type: "function",
77-
function: {
78-
name: "getTodayLeaderboard",
79-
description: "Get the leaderboard for today",
80-
parameters: {
81-
type: "object",
82-
properties: {},
83-
required: []
84-
}
85-
}
86-
}
87-
]
88-
};
89-
90-
const completion = await createChatCompletion(params);
91-
const toolCalls: ToolCall[] = [];
92-
if (completion.choices[0]?.message?.tool_calls) {
93-
for (const toolCall of completion.choices[0].message.tool_calls) {
94-
if (toolCall.type === "function" && toolCall.function?.name) {
95-
toolCalls.push({
96-
toolName: toolCall.function.name,
97-
args: toolCall.function.arguments ? JSON.parse(toolCall.function.arguments) : {}
98-
});
99-
}
100-
}
101-
}
102-
return toolCalls.length > 0 ? toolCalls : null;
103-
}
104-
10525
async function callModelToComposeMessage(
106-
userInput: UserInput,
26+
prompt: string,
10727
toolResults: ToolResults
10828
): Promise<string> {
10929
const params: ChatCompletionCreateParams = {
@@ -115,7 +35,7 @@ async function callModelToComposeMessage(
11535
},
11636
{
11737
role: "user",
118-
content: JSON.stringify(userInput)
38+
content: prompt,
11939
},
12040
{
12141
role: "system",
@@ -129,36 +49,20 @@ async function callModelToComposeMessage(
12949
}
13050

13151
// ---- MAIN FUNCTION ------------------------
132-
export async function processPrompt(tools: string, prompt: string): Promise<string> {
133-
const input: UserInput = {
134-
tools,
135-
prompt
136-
};
52+
export async function processPrompt(prompt: string): Promise<string> {
53+
console.log("🔹 Input del usuario:", prompt);
13754

138-
console.log("🔹 Input del usuario:", input);
139-
140-
// 1. First OpenAI call → ask model which tools to use
141-
const toolCalls = await callModelWithTools(input);
142-
143-
if (!toolCalls) {
144-
console.log('No tools were selected by the model');
145-
throw new Error("No tools were selected by the model");
146-
}
147-
// 2. Execute the tools
14855
const toolResults: ToolResults = {};
149-
for (const call of toolCalls) {
150-
if (call.toolName === "getLastWeekLeaderboard") {
151-
toolResults.getLastWeekLeaderboard = await getLastWeekLeaderboard();
152-
}
153-
if (call.toolName === "getLastWeekTransactions") {
154-
toolResults.getLastWeekTransactions = await getLastWeekTransactions();
155-
}
156-
if (call.toolName === "getTodayLeaderboard") {
157-
toolResults.getTodayLeaderboard = await getTodayLeaderboard();
158-
}
159-
}
56+
const toolsResults = await Promise.all([
57+
getLastWeekLeaderboard(),
58+
getLastWeekTransactions(),
59+
getTodayLeaderboard(),
60+
]);
61+
62+
toolResults.getLastWeekLeaderboard = toolsResults[0];
63+
toolResults.getLastWeekTransactions = toolsResults[1];
64+
toolResults.getTodayLeaderboard = toolsResults[2];
16065

161-
// 3. Second call → compose final message
162-
return await callModelToComposeMessage(input, toolResults);
66+
return await callModelToComposeMessage(prompt, toolResults);
16367
}
16468

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { processPrompt } from "../_agent/agent"
22
import { sendPromptMessage } from '@/app/_lib/_slack'
33

4-
export const aiWeeklySummary = async (channel: string, tools: string, prompt: string) => {
5-
const response = await processPrompt(tools, prompt)
4+
export const aiWeeklySummary = async (channel: string, prompt: string) => {
5+
const response = await processPrompt(prompt)
66
console.log('sending slack message to channel', channel)
77
await sendPromptMessage(channel, response);
88
}

app/api/ai-weekly-summary/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ export async function POST(request: Request) {
1818
}
1919
const body: AIWeeklySummaryRequest = await request.json()
2020

21-
if (!body.channel || !body.tools || !body.prompt) {
21+
if (!body.channel || !body.prompt) {
2222
return Response.json({ success: false, error: 'Missing required fields' }, { status: 400 })
2323
}
2424

2525
console.log('AI weekly summary request:', JSON.stringify(body, null, 2))
2626

2727
// Process the request asynchronously
28-
waitUntil(aiWeeklySummary(body.channel, body.tools, body.prompt))
28+
waitUntil(aiWeeklySummary(body.channel, body.prompt))
2929

3030
// Return immediate success response
3131
return Response.json({ success: true }, { status: 200 })

tests/e2e/aiWeeklySummary/aiWeeklySummary.spec.ts

Lines changed: 8 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import type { ChatCompletion } from 'openai/resources/chat/completions'
44
import * as openaiClient from '@/app/_lib/_openai/client'
55
import * as slackClient from '@/app/_lib/_slack'
66
import { prisma } from '@/app/_lib/_db/index'
7-
import openAPIToolsResponse from './mocks/openAPIToolsResponse.json'
87

98
// Mock waitUntil to execute immediately
109
vi.mock('@vercel/functions', () => ({
@@ -31,9 +30,6 @@ describe('aiWeeklySummary', () => {
3130
await prisma.transaction.deleteMany({})
3231
await prisma.user.deleteMany({})
3332
// Default mock responses for OpenAI calls
34-
// First call: tool selection (returns tool_calls)
35-
mockCreateChatCompletion.mockResolvedValueOnce(openAPIToolsResponse as ChatCompletion)
36-
3733
// Second call: message composition (returns content)
3834
mockCreateChatCompletion.mockResolvedValueOnce({
3935
choices: [
@@ -48,41 +44,16 @@ describe('aiWeeklySummary', () => {
4844
})
4945

5046
it('should call createChatCompletion with correct parameters for tool selection with empty tool results', async () => {
51-
await aiWeeklySummary('C123', 'tools', 'prompt')
52-
53-
// Verify first call (tool selection)
54-
expect(mockCreateChatCompletion).toHaveBeenNthCalledWith(
55-
1,
56-
expect.objectContaining({
57-
model: 'gpt-4.1-mini',
58-
messages: expect.arrayContaining([
59-
expect.objectContaining({
60-
role: 'system',
61-
content: 'You are an assistant that decides which tools to call based on user input.',
62-
}),
63-
expect.objectContaining({
64-
role: 'user',
65-
content: JSON.stringify({ tools: 'tools', prompt: 'prompt' }),
66-
}),
67-
]),
68-
tools: expect.arrayContaining([
69-
expect.objectContaining({
70-
type: 'function',
71-
function: expect.objectContaining({
72-
name: 'getLastWeekLeaderboard',
73-
}),
74-
}),
75-
]),
76-
})
77-
)
47+
await aiWeeklySummary('C123', 'prompt')
48+
7849
const expectedToolResults = {
7950
getLastWeekLeaderboard: [],
8051
getLastWeekTransactions: [],
8152
getTodayLeaderboard: [],
8253
}
8354
// Second call: message composition
8455
expect(mockCreateChatCompletion).toHaveBeenNthCalledWith(
85-
2,
56+
1,
8657
expect.objectContaining({
8758
model: 'gpt-4.1-mini',
8859
messages: expect.arrayContaining([
@@ -92,7 +63,7 @@ describe('aiWeeklySummary', () => {
9263
}),
9364
expect.objectContaining({
9465
role: 'user',
95-
content: JSON.stringify({ tools: 'tools', prompt: 'prompt' }),
66+
content: 'prompt',
9667
}),
9768
expect.objectContaining({
9869
role: 'system',
@@ -143,7 +114,7 @@ describe('aiWeeklySummary', () => {
143114
toUser: '<@USER22222>',
144115
},
145116
})
146-
await aiWeeklySummary('C123', 'getLastWeekLeaderboard,getLastWeekTransactions,getTodayLeaderboard', 'prompt')
117+
await aiWeeklySummary('C123', 'prompt')
147118
const expectedLeaderboard = [
148119
{
149120
toRealName: 'User 2',
@@ -176,7 +147,7 @@ describe('aiWeeklySummary', () => {
176147
}
177148
// Second call: message composition
178149
expect(mockCreateChatCompletion).toHaveBeenNthCalledWith(
179-
2,
150+
1,
180151
expect.objectContaining({
181152
model: 'gpt-4.1-mini',
182153
messages: expect.arrayContaining([
@@ -186,7 +157,7 @@ describe('aiWeeklySummary', () => {
186157
}),
187158
expect.objectContaining({
188159
role: 'user',
189-
content: JSON.stringify({ tools: 'getLastWeekLeaderboard,getLastWeekTransactions,getTodayLeaderboard', prompt: 'prompt' }),
160+
content: 'prompt',
190161
}),
191162
expect.objectContaining({
192163
role: 'system',
@@ -198,34 +169,11 @@ describe('aiWeeklySummary', () => {
198169
})
199170

200171
it('should call sendPromptMessage with the composed message', async () => {
201-
await aiWeeklySummary('C123', 'tools', 'prompt')
172+
await aiWeeklySummary('C123', 'prompt')
202173

203174
expect(mockSendPromptMessage).toHaveBeenCalledWith(
204175
'C123',
205176
'Mocked response message'
206177
)
207178
})
208-
209-
it('should throw an error if no tools were selected by the model', async () => {
210-
vi.clearAllMocks()
211-
vi.resetAllMocks()
212-
mockCreateChatCompletion.mockResolvedValueOnce({
213-
...openAPIToolsResponse,
214-
"choices": [
215-
{
216-
"index": 0,
217-
"message": {
218-
"role": "assistant",
219-
"content": null,
220-
"tool_calls": [],
221-
"refusal": null,
222-
"annotations": []
223-
},
224-
"logprobs": null,
225-
"finish_reason": "tool_calls"
226-
}
227-
],
228-
} as ChatCompletion)
229-
await expect(aiWeeklySummary('C123', 'tools', 'prompt')).rejects.toThrow('No tools were selected by the model')
230-
})
231179
})

tests/e2e/aiWeeklySummary/mocks/openAPIToolsResponse.json

Lines changed: 0 additions & 62 deletions
This file was deleted.

0 commit comments

Comments
 (0)