Skip to content

Commit 9497bce

Browse files
committed
ai: new ai package and extracted tools
1 parent aedc6bd commit 9497bce

17 files changed

Lines changed: 475 additions & 198 deletions

File tree

apps/backend/api/ai/chat.ts

Lines changed: 5 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
import type { Context } from "hono";
2-
import { openai } from "@ai-sdk/openai";
3-
import { createDataStreamResponse, generateObject, streamText } from "ai";
2+
import { createDataStreamResponse } from "ai";
43
import { Hono } from "hono";
54

6-
import { PROMPTS } from "@potential/consts";
7-
import { desc, eq, trackableLogs, trackables } from "@potential/db";
5+
import { createNewTrackableChatStream } from "@potential/ai";
86

97
import type { AppContext } from "../index";
10-
import { createConsumptionTrackables } from "./functions";
118

129
const ai = new Hono<AppContext>();
1310

@@ -33,96 +30,10 @@ ai.post("/chat", async (c: Context<AppContext>) => {
3330
execute: (dataStream) => {
3431
let accumulatedResponse = "";
3532

36-
const result = streamText({
37-
model: openai("gpt-4o-mini"),
38-
maxSteps: 10,
39-
toolCallStreaming: true,
33+
const result = createNewTrackableChatStream({
4034
messages,
41-
system: PROMPTS.CHAT.SYSTEM,
42-
tools: {
43-
getUserExistingTrackables: {
44-
description: PROMPTS.TOOLS.GET_USER_EXISTING_TRACKABLES.DESCRIPTION,
45-
parameters: PROMPTS.TOOLS.GET_USER_EXISTING_TRACKABLES.PARAMETERS,
46-
execute: async () => {
47-
const userTrackables = await db.query.trackables.findMany({
48-
where: eq(trackables.ownerId, user!.id),
49-
50-
columns: {
51-
id: true,
52-
name: true,
53-
description: true,
54-
type: true,
55-
subType: true,
56-
subTypeCustomName: true,
57-
},
58-
with: {
59-
logs: {
60-
limit: 1,
61-
orderBy: desc(trackableLogs.createdAt),
62-
columns: {
63-
createdAt: true,
64-
},
65-
},
66-
},
67-
});
68-
const consumptionTrackables = userTrackables.filter(
69-
(trackable) => trackable.type === "consumption",
70-
);
71-
const nonConsumptionTrackables = userTrackables.filter(
72-
(trackable) => trackable.type !== "consumption",
73-
);
74-
return {
75-
trackables: nonConsumptionTrackables,
76-
hasConsumptionTrackables: consumptionTrackables.length > 0,
77-
};
78-
},
79-
},
80-
generateNewNonConsumptionTrackable: {
81-
description:
82-
PROMPTS.TOOLS.GENERATE_NEW_NON_CONSUMPTION_TRACKABLE.DESCRIPTION,
83-
parameters:
84-
PROMPTS.TOOLS.GENERATE_NEW_NON_CONSUMPTION_TRACKABLE.PARAMETERS,
85-
execute: async ({ description }: { description: string }) => {
86-
const { object: newTrackable } = await generateObject({
87-
// issue with thinking models and optional fields in structured output: https://github.com/vercel/ai/issues/4662
88-
model: openai("gpt-4o-mini"),
89-
output: "array",
90-
schema:
91-
PROMPTS.TOOLS.GENERATE_NEW_NON_CONSUMPTION_TRACKABLE.EXECUTE
92-
.PROMPT.SCHEMA,
93-
system:
94-
PROMPTS.TOOLS.GENERATE_NEW_NON_CONSUMPTION_TRACKABLE.EXECUTE
95-
.PROMPT.SYSTEM,
96-
prompt: description,
97-
});
98-
newTrackable.forEach((trackable) => {
99-
console.log("TRACKABLE", {
100-
trackable,
101-
});
102-
});
103-
return { trackable: newTrackable };
104-
},
105-
},
106-
generateConsumptionTrackables: {
107-
description:
108-
PROMPTS.TOOLS.GENERATE_CONSUMPTION_TRACKABLES.DESCRIPTION,
109-
parameters:
110-
PROMPTS.TOOLS.GENERATE_CONSUMPTION_TRACKABLES.PARAMETERS,
111-
execute: async () => {
112-
console.log("🍕 GENERATE CONSUMPTION TRACKABLES");
113-
await createConsumptionTrackables({ userId: user!.id });
114-
return { completed: true };
115-
},
116-
},
117-
},
118-
onChunk(delta) {
119-
if (delta.chunk.type === "text-delta") {
120-
accumulatedResponse += delta.chunk.textDelta;
121-
}
122-
},
123-
async onFinish() {
124-
await saveToDatabase({ content: accumulatedResponse, chatId });
125-
},
35+
userId: user!.id,
36+
chatId,
12637
});
12738

12839
result.mergeIntoDataStream(dataStream);

apps/backend/api/ai/functions.ts

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +0,0 @@
1-
import type { InferInsertModel } from "@potential/db";
2-
import type { CloudTypeId } from "@potential/utils";
3-
import { and, db, eq, trackables } from "@potential/db";
4-
import { TRACKABLE_TEMPLATES } from "@potential/templates";
5-
import { cloudTypeIdGenerator } from "@potential/utils";
6-
7-
export async function createConsumptionTrackables({
8-
userId,
9-
}: {
10-
userId: CloudTypeId<"user">;
11-
}) {
12-
console.log("🍕 CREATING CONSUMPTION TRACKABLES FUNCTION");
13-
const userTrackables = await db.query.trackables.findMany({
14-
where: and(
15-
eq(trackables.ownerId, userId),
16-
eq(trackables.type, "consumption"),
17-
),
18-
columns: {
19-
id: true,
20-
},
21-
});
22-
if (userTrackables.length > 0) {
23-
return;
24-
}
25-
26-
const templates = TRACKABLE_TEMPLATES.consumption;
27-
28-
const newTrackablesToInsertArray: InferInsertModel<typeof trackables>[] = [];
29-
for (const template of Object.values(templates)) {
30-
newTrackablesToInsertArray.push({
31-
id: cloudTypeIdGenerator("trackable"),
32-
ownerId: userId,
33-
name: template.name,
34-
description: template.description,
35-
color: null,
36-
configType: template.defaultConfig.type,
37-
public: false,
38-
type: "consumption",
39-
subType: template.subType,
40-
customConfig: template.defaultConfig,
41-
});
42-
}
43-
console.log("🍕 INSERTING CONSUMPTION TRACKABLES", {
44-
newTrackablesToInsertArray,
45-
});
46-
await db.insert(trackables).values(newTrackablesToInsertArray);
47-
48-
return;
49-
}

apps/backend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"@hono/node-server": "^1.14.1",
1616
"@hono/trpc-server": "^0.3.4",
1717
"@hono/zod-validator": "^0.5.0",
18+
"@potential/ai": "workspace:*",
1819
"@potential/auth": "workspace:*",
1920
"@potential/consts": "workspace:*",
2021
"@potential/db": "workspace:*",

0 commit comments

Comments
 (0)