Skip to content

Commit 349094c

Browse files
committed
feat(ai): added base for ai suggestions
1 parent bfbd273 commit 349094c

File tree

13 files changed

+165
-50
lines changed

13 files changed

+165
-50
lines changed

package.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"dev:up": "docker-compose -f docker-compose.dev.yml up -d",
1212
"dev:down": "docker-compose -f docker-compose.dev.yml down",
1313
"build": "tsc",
14-
"convert": "node ./convertors/set-user-project-last-visit.js",
14+
"convert": "node ./convertors/set-user-workspaces-membership.js",
1515
"migrations:create": "docker-compose exec api yarn migrate-mongo create",
1616
"migrations:up": "docker-compose exec api yarn migrate-mongo up",
1717
"migrations:down": "docker-compose exec api yarn migrate-mongo down",
@@ -33,6 +33,7 @@
3333
"typescript": "^4.7.4"
3434
},
3535
"dependencies": {
36+
"@ai-sdk/openai": "^2.0.64",
3637
"@amplitude/node": "^1.10.0",
3738
"@graphql-tools/merge": "^8.3.1",
3839
"@graphql-tools/schema": "^8.5.1",
@@ -55,6 +56,7 @@
5556
"@types/node-fetch": "^2.5.4",
5657
"@types/safe-regex": "^1.1.6",
5758
"@types/uuid": "^8.3.4",
59+
"ai": "^5.0.89",
5860
"amqp-connection-manager": "^3.1.0",
5961
"amqplib": "^0.5.5",
6062
"apollo-server-express": "^3.10.0",
@@ -86,6 +88,8 @@
8688
"prom-client": "^15.1.3",
8789
"safe-regex": "^2.1.0",
8890
"ts-node-dev": "^2.0.0",
89-
"uuid": "^8.3.2"
90-
}
91-
}
91+
"uuid": "^8.3.2",
92+
"zod": "^4.1.12"
93+
},
94+
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
95+
}

src/models/eventsFactory.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const mongo = require('../mongo');
77
const Event = require('../models/event');
88
const { ObjectID } = require('mongodb');
99
const { composeEventPayloadByRepetition } = require('../utils/merge');
10-
const { openAIApi } = require('../openai');
10+
const { vercelAIApi } = require('../resolvers/vercel-ai');
1111

1212
const MAX_DB_READ_BATCH_SIZE = Number(process.env.MAX_DB_READ_BATCH_SIZE);
1313

@@ -180,22 +180,22 @@ class EventsFactory extends Factory {
180180
}
181181

182182
/**
183-
* Ask AI about solving repetition
183+
* Generate AI suggestion for the event
184184
*
185-
* @param {string} repetitionId - repetition ID
186-
* @param {string} eventId - event ID
187-
*
188-
* @return {string} - AI answer
185+
* @param {string} projectId - event's project
186+
* @param {string} eventId - event id
187+
* @param {string} originalEventId - original event id
188+
* @returns {Promise<string>} AI suggestion for the event
189189
*/
190-
async askAi(repetitionId, eventId) {
191-
const repetition = await this.getEventRepetition(repetitionId, eventId);
190+
async aiSuggestion(eventId, originalEventId) {
191+
const repetition = await this.getEventRepetition(eventId, originalEventId);
192192

193193
if (!repetition) {
194194
throw new Error('Repetition not found');
195195
}
196196

197-
const payload = repetition.event.payload;
198-
const solution = await openAIApi.solveEvent(payload);
197+
const payload = repetition.payload;
198+
const solution = await vercelAIApi.generateSuggestion(payload);
199199

200200
return solution;
201201
}

src/openai/index.ts

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

src/openai/instructions/cto.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/openai/types.ts

Whitespace-only changes.

src/resolvers/event.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,18 @@ module.exports = {
8989
return factory.findChartData(days, timezoneOffset, groupHash);
9090
},
9191

92-
async askAi({ projectId, id: eventId, originalEventId }, _args, context) {
92+
/**
93+
* Return AI suggestion for the event
94+
*
95+
* @param {string} projectId - event's project
96+
* @param {string} eventId - event id
97+
* @param {string} originalEventId - original event id
98+
* @returns {Promise<string>} AI suggestion for the event
99+
*/
100+
async aiSuggestion({ projectId, id: eventId, originalEventId }, _args, context) {
93101
const factory = getEventsFactory(context, projectId);
94-
const aiAnswer = await factory.askAi(eventId, originalEventId);
95102

96-
return aiAnswer;
103+
return factory.aiSuggestion(eventId, originalEventId);
97104
},
98105

99106
/**

src/resolvers/vercel-ai/index.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { EventAddons, EventData } from '@hawk.so/types';
2+
import { generateText } from 'ai';
3+
import { openai } from '@ai-sdk/openai';
4+
import { eventSolvingInput } from './inputs/eventSolving';
5+
import { ctoInstruction } from './instructions/cto';
6+
7+
/**
8+
* Vercel AI API
9+
*/
10+
class VercelAIApi {
11+
/**
12+
* Model ID
13+
*/
14+
private readonly modelId: string;
15+
16+
constructor() {
17+
/**
18+
* @todo make it dynamic, get from project settings
19+
*/
20+
this.modelId = 'gpt-4o';
21+
}
22+
23+
/**
24+
* Generate AI suggestion for the event
25+
*
26+
* @param {EventData<EventAddons>} payload - event data
27+
* @returns {Promise<string>} AI suggestion for the event
28+
*/
29+
public async generateSuggestion(payload: EventData<EventAddons>) {
30+
const { text } = await generateText({
31+
model: openai(this.modelId),
32+
system: ctoInstruction,
33+
prompt: eventSolvingInput(payload),
34+
});
35+
36+
return text;
37+
}
38+
}
39+
40+
export const vercelAIApi = new VercelAIApi();

src/openai/inputs/eventSolving.ts renamed to src/resolvers/vercel-ai/inputs/eventSolving.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { EventData, EventAddons } from "@hawk.so/types"
1+
import { EventData, EventAddons } from '@hawk.so/types';
22

33
export const eventSolvingInput = (payload: EventData<EventAddons>) => `
44
@@ -12,4 +12,4 @@ Response:
1212
"solution": "...",
1313
"explanation": "..."
1414
}
15-
`
15+
`;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const ctoInstruction = 'Ты технический директор ИТ компании, тебе нужно пояснить ошибку и предложить решение';

src/typeDefs/event.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,9 @@ type Event {
263263
repetitionsPortion(cursor: String = null, limit: Int = 10): RepetitionsPortion!
264264
265265
"""
266-
AI solution for the event
266+
AI suggestion for the event
267267
"""
268-
askAi: String!
268+
aiSuggestion: String!
269269
270270
"""
271271
Array of users who visited event

0 commit comments

Comments
 (0)