Skip to content

Commit 0301683

Browse files
committed
looks good to me
1 parent 09ea6c2 commit 0301683

File tree

5 files changed

+52
-53
lines changed

5 files changed

+52
-53
lines changed

.gitattributes

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
types/database.types.ts linguist-generated
1+
app/types/database.types.ts linguist-generated

app/composables/use-topic.ts

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,53 +9,60 @@ export default async (supa: Supa, id: string) => {
99
.throwOnError()
1010
).data);
1111

12-
const syncTopic = () => {
13-
return supa
14-
.from('topics')
12+
const syncTopic = async () => {
13+
return await supa.from('topics')
1514
.update({
1615
title: data.value.title,
1716
description: data.value.description,
1817
})
1918
.eq('id', id)
20-
.select('*')
2119
.throwOnError();
2220
};
2321

24-
const syncTimelineNode = (id: string) => {
22+
const syncTimelineNode = async (id: string) => {
2523
const node = toRaw(data.value.timeline_nodes.find(t => t.id === id));
2624
if (node) {
27-
return supa.from('timeline_nodes')
28-
.upsert({
29-
id: node.id,
25+
await supa.from('timeline_nodes')
26+
.update({
3027
title: node.title,
3128
time: node.time,
3229
topic_id: node.topic_id,
3330
})
34-
.select('*')
31+
.eq('id', id)
3532
.throwOnError();
3633
} else {
37-
return supa.from('timeline_nodes')
34+
await supa.from('timeline_nodes')
3835
.delete()
3936
.eq('id', id)
4037
.throwOnError();
4138
}
4239
};
4340

44-
const syncTask = (id: string) => {
41+
const addTimelineNode = async () => {
42+
const { data: n } = await supa.from('timeline_nodes')
43+
.insert({
44+
title: '',
45+
topic_id: id,
46+
})
47+
.select('*')
48+
.throwOnError();
49+
data.value.timeline_nodes.push(n[0]!);
50+
}
51+
52+
const syncTask = async (id: string) => {
4553
const task = toRaw(data.value.tasks.find(t => t.id === id));
4654
if (task) {
47-
return supa.from('tasks')
55+
await supa.from('tasks')
4856
.upsert(task)
4957
.eq('id', id)
50-
.select('*')
5158
.throwOnError();
5259
} else {
53-
return supa.from('tasks')
60+
await supa.from('tasks')
5461
.delete()
5562
.eq('id', id)
5663
.throwOnError();
5764
}
5865
};
5966

60-
return { data, syncTopic, syncTimelineNode, syncTask };
67+
return { data, syncTopic, syncTimelineNode, addTimelineNode, syncTask };
6168
};

app/pages/topic/[id].vue

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const {
1010
data: topic,
1111
syncTopic,
1212
syncTimelineNode,
13+
addTimelineNode,
1314
syncTask,
1415
} = await useTopic(supa, route.params.id as string);
1516
@@ -20,16 +21,6 @@ function generate() {
2021
});
2122
}
2223
23-
function addTimelineNode() {
24-
const id = crypto.randomUUID();
25-
topic.value.timeline_nodes.push({
26-
id,
27-
time: new Date(),
28-
description: '',
29-
});
30-
syncTimelineNode(id);
31-
}
32-
3324
function removeTimelineNode(id: string) {
3425
topic.value.timeline_nodes = topic.value.timeline_nodes.filter(n => n.id !== id);
3526
syncTimelineNode(id);
@@ -41,6 +32,11 @@ function onPickDate(node: Tables<'timeline_nodes'>, v: CalendarDate) {
4132
node.time = v.toString();
4233
syncTimelineNode(node.id);
4334
}
35+
36+
function removeTask(id: string) {
37+
topic.value.tasks = topic.value.tasks.filter(t => t.id !== id);
38+
syncTask(id);
39+
}
4440
</script>
4541

4642
<template>
@@ -58,7 +54,7 @@ function onPickDate(node: Tables<'timeline_nodes'>, v: CalendarDate) {
5854
<template #body>
5955
<UForm v-if="topic" class="space-y-4" :state="topic">
6056
<UFormField label="Description" hint="Describe it..." size="xl">
61-
<UTextarea v-model="topic.description" class="w-full" @change="syncTopic" />
57+
<UTextarea v-model="topic.description" class="w-full" @change="syncTopic()" />
6258
</UFormField>
6359

6460
<div class="grid grid-cols-[1fr_auto_1fr] items-start w-full gap-3">
@@ -99,15 +95,15 @@ function onPickDate(node: Tables<'timeline_nodes'>, v: CalendarDate) {
9995
variant="outline"
10096
color="neutral"
10197
class="mt-2 self-start"
102-
@click="addTimelineNode"
98+
@click="addTimelineNode()"
10399
/>
104100
</UFormField>
105101

106102
<div class="h-full border-l ring-inset self-stretch mt-6" />
107103

108104
<UFormField label="Recommended Tasks" size="xl" :ui="{ label: 'items-start' }">
109105
<ul>
110-
<template v-for="(task) in topic.tasks">
106+
<template v-for="task in topic.tasks">
111107
<UCheckbox
112108
v-if="task.status === 'pending'"
113109
:key="task.id"
@@ -117,7 +113,7 @@ function onPickDate(node: Tables<'timeline_nodes'>, v: CalendarDate) {
117113
@update:model-value="task.status = 'accepted'"
118114
>
119115
<template #label>
120-
<UButton variant="soft" color="neutral" size="xs" icon="lucide:trash-2" />
116+
<UButton variant="soft" color="neutral" size="xs" icon="lucide:trash-2" @click="removeTask(task.id)" />
121117
{{ ' ' }}
122118
<span class="align-top">{{ task.title }}</span>
123119
</template>

server/api/model-response.schema.json

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

server/api/request-tasks.post.ts

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import process from 'node:process';
22
import { serverSupabaseClient, serverSupabaseUser } from '#supabase/server';
33
import { ChatDeepSeek } from '@langchain/deepseek';
44
import { z } from 'zod';
5-
import ModelResponseSchema from './model-response.schema.json';
65

76
const Body = z.object({
87
id: z.string().uuid(),
@@ -31,33 +30,42 @@ export default defineEventHandler(async (ev) => {
3130

3231
const res = await model.invoke([{
3332
role: 'system',
34-
content: `You are a helper assistant. You need to help users break down a big goal into several executable small tasks.
33+
content: `You are a helper assistant. You need to help users guide users to obtain more information through specific actions to assist in decision-making.
3534
You may have given suggestions to users before.
3635
You will receive the following information:
3736
- User's major goals
3837
- Description
3938
- Progress
4039
- Existing tasks
4140
You must suggest tasks that are:
42-
1. Small, clear, and executable, like KRs.
43-
2. Related to the user's major goals and description
44-
3. Standing neutral and friendly
45-
4. Not using markdown
41+
1. Related to the user's major goals and description
42+
2. Standing neutral and friendly
43+
3. Not using markdown
44+
4. Including measurable metric, target value, clear timeframe, data source
45+
5. Using the same language as the user
4646
You must NOT suggest tasks that are:
4747
1. Repeat the same task, including the same task with different wording
4848
2. Already in the tasks table
4949
3. Already rejected by the user
5050
4. Not executable or off-topic
5151
5. Too broad or vague
52-
You must respond with a list of tasks in the following JSON format:
53-
\`\`\`json
54-
${JSON.stringify(ModelResponseSchema, null, 2)}
55-
\`\`\`
52+
You must respond in JSON without any explanation or markdown.
53+
The JSON should be an array of string, each string is a task.
54+
Correct example:
55+
Topic: Decide on a new car
56+
Description: I want to buy a new car, but I don't know which one to choose. I have a budget of $30,000 and I love long-distance travel. I don't care a lot about its appearance.
57+
Progress: Not started.
58+
Recommended tasks:
59+
1. Go to SUV and MPV car comparison websites to get more information in 1 hour.
60+
2. Contact 3 friends who have bought cars in the past 2 years and ask them about their experiences.
61+
3. Checkout their negative reviews on the car forums.
62+
5663
Current time is ${new Date().toISOString()}.`,
5764
}, {
5865
role: 'user',
5966
content: JSON.stringify(data[0]),
6067
}]);
68+
console.log(res);
6169

62-
return res.content;
70+
return JSON.parse(res.text) as string[];
6371
});

0 commit comments

Comments
 (0)