@tuturuuu/ai 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/README.md +76 -0
  2. package/package.json +106 -0
  3. package/src/api-key-hash.ts +28 -0
  4. package/src/calendar/events.ts +34 -0
  5. package/src/calendar/route.ts +114 -0
  6. package/src/chat/credit-source.ts +1 -0
  7. package/src/chat/google/chat-request-schema.ts +150 -0
  8. package/src/chat/google/default-system-instruction.ts +198 -0
  9. package/src/chat/google/message-file-processing.ts +212 -0
  10. package/src/chat/google/mira-step-preparation.ts +221 -0
  11. package/src/chat/google/new/route.ts +368 -0
  12. package/src/chat/google/route-auth.ts +81 -0
  13. package/src/chat/google/route-chat-resolution.ts +98 -0
  14. package/src/chat/google/route-credits.ts +61 -0
  15. package/src/chat/google/route-message-preparation.ts +331 -0
  16. package/src/chat/google/route-mira-runtime.ts +206 -0
  17. package/src/chat/google/route.ts +632 -0
  18. package/src/chat/google/stream-finish-persistence.ts +722 -0
  19. package/src/chat/google/summary/route.ts +153 -0
  20. package/src/chat/mira-render-ui-policy.ts +540 -0
  21. package/src/chat/mira-system-instruction.ts +484 -0
  22. package/src/chat-sdk/adapters.ts +389 -0
  23. package/src/chat-sdk/registry.ts +197 -0
  24. package/src/chat-sdk.ts +33 -0
  25. package/src/core.ts +3 -0
  26. package/src/credits/cap-output-tokens.ts +90 -0
  27. package/src/credits/check-credits.ts +232 -0
  28. package/src/credits/constants.ts +30 -0
  29. package/src/credits/index.ts +46 -0
  30. package/src/credits/model-mapping.ts +92 -0
  31. package/src/credits/reservations.ts +514 -0
  32. package/src/credits/resolve-plan-model.ts +219 -0
  33. package/src/credits/sync-gateway-models.ts +351 -0
  34. package/src/credits/types.ts +109 -0
  35. package/src/credits/use-ai-credits.ts +3 -0
  36. package/src/embeddings/metered.ts +283 -0
  37. package/src/executions/route.ts +137 -0
  38. package/src/generate/route.ts +411 -0
  39. package/src/hooks.ts +7 -0
  40. package/src/meetings/summary/route.ts +7 -0
  41. package/src/meetings/transcription/route.ts +134 -0
  42. package/src/memory/client.ts +158 -0
  43. package/src/memory/config.ts +38 -0
  44. package/src/memory/index.ts +32 -0
  45. package/src/memory/ingest.ts +51 -0
  46. package/src/memory/middleware.ts +35 -0
  47. package/src/memory/operations.ts +480 -0
  48. package/src/memory/scope.ts +102 -0
  49. package/src/memory/settings.ts +121 -0
  50. package/src/memory/types.ts +101 -0
  51. package/src/memory/workspace.ts +36 -0
  52. package/src/memory.ts +1 -0
  53. package/src/mind/patch.ts +146 -0
  54. package/src/mind/route.ts +687 -0
  55. package/src/mind/tools.ts +1500 -0
  56. package/src/mind/types.ts +20 -0
  57. package/src/object/core.ts +3 -0
  58. package/src/object/flashcards/route.ts +140 -0
  59. package/src/object/quizzes/explanation/route.ts +145 -0
  60. package/src/object/quizzes/route.ts +142 -0
  61. package/src/object/types.ts +187 -0
  62. package/src/object/year-plan/route.ts +196 -0
  63. package/src/react.ts +1 -0
  64. package/src/scheduling/algorithm.ts +791 -0
  65. package/src/scheduling/default.ts +36 -0
  66. package/src/scheduling/duration-optimizer.ts +689 -0
  67. package/src/scheduling/index.ts +79 -0
  68. package/src/scheduling/priority-calculator.ts +187 -0
  69. package/src/scheduling/recurrence-calculator.ts +621 -0
  70. package/src/scheduling/templates.ts +892 -0
  71. package/src/scheduling/types.ts +136 -0
  72. package/src/scheduling/web-adapter.ts +308 -0
  73. package/src/scheduling.ts +6 -0
  74. package/src/supported-actions.ts +1 -0
  75. package/src/supported-providers.ts +6 -0
  76. package/src/tools/context-builder.ts +372 -0
  77. package/src/tools/core.ts +1 -0
  78. package/src/tools/definitions/calendar.ts +106 -0
  79. package/src/tools/definitions/finance.ts +197 -0
  80. package/src/tools/definitions/image.ts +74 -0
  81. package/src/tools/definitions/memory.ts +83 -0
  82. package/src/tools/definitions/meta.ts +154 -0
  83. package/src/tools/definitions/render-ui.ts +81 -0
  84. package/src/tools/definitions/tasks.ts +343 -0
  85. package/src/tools/definitions/time-tracking.ts +381 -0
  86. package/src/tools/definitions/workspace-context.ts +45 -0
  87. package/src/tools/definitions/workspace-user-chat.ts +111 -0
  88. package/src/tools/executors/calendar.ts +371 -0
  89. package/src/tools/executors/chat.ts +15 -0
  90. package/src/tools/executors/finance.ts +638 -0
  91. package/src/tools/executors/helpers/encryption.ts +107 -0
  92. package/src/tools/executors/image.ts +247 -0
  93. package/src/tools/executors/markitdown.ts +684 -0
  94. package/src/tools/executors/memory.ts +277 -0
  95. package/src/tools/executors/parallel-checks.ts +176 -0
  96. package/src/tools/executors/qr.ts +170 -0
  97. package/src/tools/executors/scope-helpers.ts +192 -0
  98. package/src/tools/executors/search.ts +149 -0
  99. package/src/tools/executors/settings.ts +40 -0
  100. package/src/tools/executors/tasks.ts +1087 -0
  101. package/src/tools/executors/theme.ts +23 -0
  102. package/src/tools/executors/timer/timer-categories-executor.ts +110 -0
  103. package/src/tools/executors/timer/timer-category-mutations.ts +240 -0
  104. package/src/tools/executors/timer/timer-goal-mutations.ts +323 -0
  105. package/src/tools/executors/timer/timer-goals-executor.ts +272 -0
  106. package/src/tools/executors/timer/timer-helpers.ts +372 -0
  107. package/src/tools/executors/timer/timer-mutation-schemas.ts +160 -0
  108. package/src/tools/executors/timer/timer-mutation-types.ts +212 -0
  109. package/src/tools/executors/timer/timer-mutations.ts +19 -0
  110. package/src/tools/executors/timer/timer-queries.ts +18 -0
  111. package/src/tools/executors/timer/timer-session-lifecycle.ts +299 -0
  112. package/src/tools/executors/timer/timer-session-mutations.ts +10 -0
  113. package/src/tools/executors/timer/timer-session-queries.ts +153 -0
  114. package/src/tools/executors/timer/timer-session-updates.ts +200 -0
  115. package/src/tools/executors/timer/timer-sessions-executor.ts +91 -0
  116. package/src/tools/executors/timer/timer-stats-executor.ts +157 -0
  117. package/src/tools/executors/timer.ts +22 -0
  118. package/src/tools/executors/user.ts +60 -0
  119. package/src/tools/executors/workspace.ts +135 -0
  120. package/src/tools/json-render-catalog.ts +875 -0
  121. package/src/tools/mira-tool-definitions.ts +55 -0
  122. package/src/tools/mira-tool-dispatcher.ts +265 -0
  123. package/src/tools/mira-tool-metadata.ts +164 -0
  124. package/src/tools/mira-tool-names.ts +95 -0
  125. package/src/tools/mira-tool-render-ui.ts +54 -0
  126. package/src/tools/mira-tool-types.ts +17 -0
  127. package/src/tools/mira-tools.ts +167 -0
  128. package/src/tools/normalize-render-ui-input.ts +321 -0
  129. package/src/tools/workspace-context.ts +233 -0
  130. package/src/types.ts +38 -0
@@ -0,0 +1,20 @@
1
+ export type {
2
+ MindAiPatch,
3
+ MindAiPatchRecord,
4
+ MindBoard,
5
+ MindBoardSnapshot,
6
+ MindBoardStatus,
7
+ MindBoardSummary,
8
+ MindEdge,
9
+ MindEdgeType,
10
+ MindEntityLinkType,
11
+ MindGroup,
12
+ MindHorizon,
13
+ MindJsonObject,
14
+ MindNode,
15
+ MindNodeLink,
16
+ MindNodeStatus,
17
+ MindNodeType,
18
+ MindPatchOperation,
19
+ MindTag,
20
+ } from '@tuturuuu/types/db';
@@ -0,0 +1,3 @@
1
+ import { experimental_useObject as useObject } from '@ai-sdk/react';
2
+
3
+ export { useObject };
@@ -0,0 +1,140 @@
1
+ import { google } from '@ai-sdk/google';
2
+ import {
3
+ createAdminClient,
4
+ createClient,
5
+ } from '@tuturuuu/supabase/next/server';
6
+ import { Output, streamText } from 'ai';
7
+ import { NextResponse } from 'next/server';
8
+ import { withAiMemory } from '../../memory';
9
+ import { flashcardSchema } from '../types';
10
+
11
+ const DEFAULT_MODEL_NAME = 'gemini-3.1-flash-lite';
12
+
13
+ export async function POST(req: Request) {
14
+ const sbAdmin = await createAdminClient();
15
+
16
+ const { wsId, context } = (await req.json()) as {
17
+ wsId?: string;
18
+ context?: string;
19
+ };
20
+
21
+ try {
22
+ // if (!id) return new Response('Missing chat ID', { status: 400 });
23
+ if (!wsId) return new Response('Missing workspace ID', { status: 400 });
24
+ if (!context) return new Response('Missing context', { status: 400 });
25
+
26
+ // eslint-disable-next-line no-undef
27
+ const apiKey = process.env.GOOGLE_GENERATIVE_AI_API_KEY;
28
+ if (!apiKey) return new Response('Missing API key', { status: 400 });
29
+
30
+ const supabase = await createClient();
31
+
32
+ const {
33
+ data: { user },
34
+ } = await supabase.auth.getUser();
35
+
36
+ if (!user) return new Response('Unauthorized', { status: 401 });
37
+
38
+ const { count, error } = await sbAdmin
39
+ .from('workspace_secrets')
40
+ .select('*', { count: 'exact', head: true })
41
+ .eq('ws_id', wsId)
42
+ .eq('name', 'ENABLE_CHAT')
43
+ .eq('value', 'true');
44
+
45
+ if (error) return new Response(error.message, { status: 500 });
46
+ if (count === 0)
47
+ return new Response('You are not allowed to use this feature.', {
48
+ status: 401,
49
+ });
50
+
51
+ // let chatId = id;
52
+
53
+ // if (!chatId) {
54
+ // const { data, error } = await sbAdmin
55
+ // .from('ai_chats')
56
+ // .select('id')
57
+ // .eq('creator_id', user?.id)
58
+ // .order('created_at', { ascending: false })
59
+ // .limit(1)
60
+ // .single();
61
+
62
+ // if (error) return new Response(error.message, { status: 500 });
63
+ // if (!data) return new Response('Internal Server Error', { status: 500 });
64
+
65
+ // chatId = data.id;
66
+ // }
67
+
68
+ const result = streamText({
69
+ model: await withAiMemory({
70
+ customId: `flashcards-${Date.now()}`,
71
+ model: google(DEFAULT_MODEL_NAME),
72
+ product: 'education',
73
+ source: 'flashcard_generation',
74
+ surface: 'flashcard_generation',
75
+ userId: user.id,
76
+ wsId,
77
+ }),
78
+ prompt: `Generate 10 flashcards with the following context (in the same language as the provided context): ${context}`,
79
+ output: Output.object({ schema: flashcardSchema }),
80
+ providerOptions: {
81
+ google: {
82
+ safetySettings: [
83
+ {
84
+ category: 'HARM_CATEGORY_DANGEROUS_CONTENT',
85
+ threshold: 'BLOCK_NONE',
86
+ },
87
+ {
88
+ category: 'HARM_CATEGORY_HATE_SPEECH',
89
+ threshold: 'BLOCK_NONE',
90
+ },
91
+ {
92
+ category: 'HARM_CATEGORY_HARASSMENT',
93
+ threshold: 'BLOCK_NONE',
94
+ },
95
+ {
96
+ category: 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
97
+ threshold: 'BLOCK_NONE',
98
+ },
99
+ ],
100
+ },
101
+ },
102
+ // onFinish: async (response) => {
103
+ // console.log('AI Response:', response);
104
+ // if (!response.object) {
105
+ // console.log('No content found');
106
+ // throw new Error('No content found');
107
+ // }
108
+ // const { error } = await sbAdmin.from('ai_chat_messages').insert({
109
+ // chat_id: chatId,
110
+ // creator_id: user.id,
111
+ // content: response.text,
112
+ // role: 'ASSISTANT',
113
+ // model: model.toLowerCase(),
114
+ // finish_reason: response.finishReason,
115
+ // prompt_tokens: response.usage.promptTokens,
116
+ // completion_tokens: response.usage.completionTokens,
117
+ // metadata: { source: 'Tuturuuu' },
118
+ // });
119
+ // if (error) {
120
+ // console.log('ERROR ORIGIN: ROOT COMPLETION');
121
+ // console.log(error);
122
+ // throw new Error(error.message);
123
+ // }
124
+ // console.log('AI Response saved to database');
125
+ // },
126
+ });
127
+
128
+ return result.toTextStreamResponse();
129
+ } catch (error) {
130
+ console.log(error);
131
+ return NextResponse.json(
132
+ {
133
+ message: `## Edge API Failure\nCould not complete the request. Please view the **Stack trace** below.\n\`\`\`bash\n${(error as Error)?.stack || 'No stack trace available'}`,
134
+ },
135
+ {
136
+ status: 500,
137
+ }
138
+ );
139
+ }
140
+ }
@@ -0,0 +1,145 @@
1
+ import { google } from '@ai-sdk/google';
2
+ import {
3
+ createAdminClient,
4
+ createClient,
5
+ } from '@tuturuuu/supabase/next/server';
6
+ import { Output, streamText } from 'ai';
7
+ import { NextResponse } from 'next/server';
8
+ import { withAiMemory } from '../../../memory';
9
+ import { quizOptionExplanationSchema } from '../../types';
10
+
11
+ const DEFAULT_MODEL_NAME = 'gemini-3.1-flash-lite';
12
+
13
+ export async function POST(req: Request) {
14
+ const sbAdmin = await createAdminClient();
15
+
16
+ const { wsId, question, option } = (await req.json()) as {
17
+ wsId?: string;
18
+ question?: string;
19
+ option?: {
20
+ is_correct?: boolean;
21
+ value?: string;
22
+ };
23
+ };
24
+
25
+ try {
26
+ // if (!id) return new Response('Missing chat ID', { status: 400 });
27
+ if (!wsId) return new Response('Missing workspace ID', { status: 400 });
28
+ if (!question || !option)
29
+ return new Response('Missing context', { status: 400 });
30
+
31
+ // eslint-disable-next-line no-undef
32
+ const apiKey = process.env.GOOGLE_GENERATIVE_AI_API_KEY;
33
+ if (!apiKey) return new Response('Missing API key', { status: 400 });
34
+
35
+ const supabase = await createClient();
36
+
37
+ const {
38
+ data: { user },
39
+ } = await supabase.auth.getUser();
40
+
41
+ if (!user) return new Response('Unauthorized', { status: 401 });
42
+
43
+ const { count, error } = await sbAdmin
44
+ .from('workspace_secrets')
45
+ .select('*', { count: 'exact', head: true })
46
+ .eq('ws_id', wsId)
47
+ .eq('name', 'ENABLE_CHAT')
48
+ .eq('value', 'true');
49
+
50
+ if (error) return new Response(error.message, { status: 500 });
51
+ if (count === 0)
52
+ return new Response('You are not allowed to use this feature.', {
53
+ status: 401,
54
+ });
55
+
56
+ // let chatId = id;
57
+
58
+ // if (!chatId) {
59
+ // const { data, error } = await sbAdmin
60
+ // .from('ai_chats')
61
+ // .select('id')
62
+ // .eq('creator_id', user?.id)
63
+ // .order('created_at', { ascending: false })
64
+ // .limit(1)
65
+ // .single();
66
+
67
+ // if (error) return new Response(error.message, { status: 500 });
68
+ // if (!data) return new Response('Internal Server Error', { status: 500 });
69
+
70
+ // chatId = data.id;
71
+ // }
72
+
73
+ const result = streamText({
74
+ model: await withAiMemory({
75
+ customId: `quiz-explanation-${Date.now()}`,
76
+ model: google(DEFAULT_MODEL_NAME),
77
+ product: 'education',
78
+ source: 'quiz_explanation',
79
+ surface: 'quiz_explanation',
80
+ userId: user.id,
81
+ wsId,
82
+ }),
83
+ prompt: `Generate an explanation with the following context: \n\n"""Question: ${question}""" \n\n"""Option: ${option.value}"""\n\nIs this option correct? ${option.is_correct ? 'Yes' : 'No'}\n\nNOTE: Provide it in the same language as the question and option, be concise and clear.`,
84
+ output: Output.object({ schema: quizOptionExplanationSchema }),
85
+ providerOptions: {
86
+ google: {
87
+ safetySettings: [
88
+ {
89
+ category: 'HARM_CATEGORY_DANGEROUS_CONTENT',
90
+ threshold: 'BLOCK_NONE',
91
+ },
92
+ {
93
+ category: 'HARM_CATEGORY_HATE_SPEECH',
94
+ threshold: 'BLOCK_NONE',
95
+ },
96
+ {
97
+ category: 'HARM_CATEGORY_HARASSMENT',
98
+ threshold: 'BLOCK_NONE',
99
+ },
100
+ {
101
+ category: 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
102
+ threshold: 'BLOCK_NONE',
103
+ },
104
+ ],
105
+ },
106
+ },
107
+ // onFinish: async (response) => {
108
+ // console.log('AI Response:', response);
109
+ // if (!response.object) {
110
+ // console.log('No content found');
111
+ // throw new Error('No content found');
112
+ // }
113
+ // const { error } = await sbAdmin.from('ai_chat_messages').insert({
114
+ // chat_id: chatId,
115
+ // creator_id: user.id,
116
+ // content: response.text,
117
+ // role: 'ASSISTANT',
118
+ // model: model.toLowerCase(),
119
+ // finish_reason: response.finishReason,
120
+ // prompt_tokens: response.usage.promptTokens,
121
+ // completion_tokens: response.usage.completionTokens,
122
+ // metadata: { source: 'Tuturuuu' },
123
+ // });
124
+ // if (error) {
125
+ // console.log('ERROR ORIGIN: ROOT COMPLETION');
126
+ // console.log(error);
127
+ // throw new Error(error.message);
128
+ // }
129
+ // console.log('AI Response saved to database');
130
+ // },
131
+ });
132
+
133
+ return result.toTextStreamResponse();
134
+ } catch (error) {
135
+ console.log(error);
136
+ return NextResponse.json(
137
+ {
138
+ message: `## Edge API Failure\nCould not complete the request. Please view the **Stack trace** below.\n\`\`\`bash\n${(error as Error)?.stack || 'No stack trace available'}`,
139
+ },
140
+ {
141
+ status: 500,
142
+ }
143
+ );
144
+ }
145
+ }
@@ -0,0 +1,142 @@
1
+ import { google } from '@ai-sdk/google';
2
+ import {
3
+ createAdminClient,
4
+ createClient,
5
+ } from '@tuturuuu/supabase/next/server';
6
+ import { Output, streamText } from 'ai';
7
+ import { NextResponse } from 'next/server';
8
+ import { withAiMemory } from '../../memory';
9
+ import { quizSchema } from '../types';
10
+
11
+ const DEFAULT_MODEL_NAME = 'gemini-3.1-flash-lite';
12
+
13
+ export async function POST(req: Request) {
14
+ const sbAdmin = await createAdminClient();
15
+
16
+ const { wsId, context } = (await req.json()) as {
17
+ wsId?: string;
18
+ context?: string;
19
+ };
20
+
21
+ try {
22
+ // if (!id) return new Response('Missing chat ID', { status: 400 });
23
+ if (!wsId) return new Response('Missing workspace ID', { status: 400 });
24
+ if (!context) return new Response('Missing context', { status: 400 });
25
+
26
+ // eslint-disable-next-line no-undef
27
+ const apiKey = process.env.GOOGLE_GENERATIVE_AI_API_KEY;
28
+ if (!apiKey) return new Response('Missing API key', { status: 400 });
29
+
30
+ const supabase = await createClient();
31
+
32
+ const {
33
+ data: { user },
34
+ } = await supabase.auth.getUser();
35
+
36
+ if (!user) return new Response('Unauthorized', { status: 401 });
37
+
38
+ const { count, error } = await sbAdmin
39
+ .from('workspace_secrets')
40
+ .select('*', { count: 'exact', head: true })
41
+ .eq('ws_id', wsId)
42
+ .eq('name', 'ENABLE_CHAT')
43
+ .eq('value', 'true');
44
+
45
+ if (error) return new Response(error.message, { status: 500 });
46
+ if (count === 0)
47
+ return new Response('You are not allowed to use this feature.', {
48
+ status: 401,
49
+ });
50
+
51
+ // let chatId = id;
52
+
53
+ // if (!chatId) {
54
+ // const { data, error } = await sbAdmin
55
+ // .from('ai_chats')
56
+ // .select('id')
57
+ // .eq('creator_id', user?.id)
58
+ // .order('created_at', { ascending: false })
59
+ // .limit(1)
60
+ // .single();
61
+
62
+ // if (error) return new Response(error.message, { status: 500 });
63
+ // if (!data) return new Response('Internal Server Error', { status: 500 });
64
+
65
+ // chatId = data.id;
66
+ // }
67
+
68
+ const result = streamText({
69
+ model: await withAiMemory({
70
+ customId: `quiz-${Date.now()}`,
71
+ model: google(DEFAULT_MODEL_NAME),
72
+ product: 'education',
73
+ source: 'quiz_generation',
74
+ surface: 'quiz_generation',
75
+ userId: user.id,
76
+ wsId,
77
+ }),
78
+ prompt:
79
+ `Generate 10 quizzes with the following context (in the same language as the provided context): ` +
80
+ context,
81
+ output: Output.object({ schema: quizSchema }),
82
+ providerOptions: {
83
+ google: {
84
+ safetySettings: [
85
+ {
86
+ category: 'HARM_CATEGORY_DANGEROUS_CONTENT',
87
+ threshold: 'BLOCK_NONE',
88
+ },
89
+ {
90
+ category: 'HARM_CATEGORY_HATE_SPEECH',
91
+ threshold: 'BLOCK_NONE',
92
+ },
93
+ {
94
+ category: 'HARM_CATEGORY_HARASSMENT',
95
+ threshold: 'BLOCK_NONE',
96
+ },
97
+ {
98
+ category: 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
99
+ threshold: 'BLOCK_NONE',
100
+ },
101
+ ],
102
+ },
103
+ },
104
+ // onFinish: async (response) => {
105
+ // console.log('AI Response:', response);
106
+ // if (!response.object) {
107
+ // console.log('No content found');
108
+ // throw new Error('No content found');
109
+ // }
110
+ // const { error } = await sbAdmin.from('ai_chat_messages').insert({
111
+ // chat_id: chatId,
112
+ // creator_id: user.id,
113
+ // content: response.text,
114
+ // role: 'ASSISTANT',
115
+ // model: model.toLowerCase(),
116
+ // finish_reason: response.finishReason,
117
+ // prompt_tokens: response.usage.promptTokens,
118
+ // completion_tokens: response.usage.completionTokens,
119
+ // metadata: { source: 'Tuturuuu' },
120
+ // });
121
+ // if (error) {
122
+ // console.log('ERROR ORIGIN: ROOT COMPLETION');
123
+ // console.log(error);
124
+ // throw new Error(error.message);
125
+ // }
126
+ // console.log('AI Response saved to database');
127
+ // },
128
+ });
129
+
130
+ return result.toTextStreamResponse();
131
+ } catch (error) {
132
+ console.log(error);
133
+ return NextResponse.json(
134
+ {
135
+ message: `## Edge API Failure\nCould not complete the request. Please view the **Stack trace** below.\n\`\`\`bash\n${(error as Error)?.stack || 'No stack trace available'}`,
136
+ },
137
+ {
138
+ status: 500,
139
+ }
140
+ );
141
+ }
142
+ }
@@ -0,0 +1,187 @@
1
+ import { z } from 'zod';
2
+
3
+ export const flashcardSchema = z.object({
4
+ flashcards: z.array(
5
+ z.object({
6
+ front: z.string().describe('Question. Do not use emojis or links.'),
7
+ back: z.string().describe('Answer. Do not use emojis or links.'),
8
+ })
9
+ ),
10
+ });
11
+
12
+ export const quizSchema = z.object({
13
+ quizzes: z.array(
14
+ z.object({
15
+ question: z.string().describe('Question. Do not use emojis or links.'),
16
+ quiz_options: z.array(
17
+ z.object({
18
+ value: z.string().describe('Option. Do not use emojis or links.'),
19
+ explanation: z
20
+ .string()
21
+ .describe(
22
+ 'Explain why this option is correct or incorrect, if it is incorrect, explain possible misconceptions and what made the option wrong with respect to the question, if it is correct, explain why it is correct. Be as detailed as possible.'
23
+ ),
24
+ is_correct: z.boolean().describe('This option is a correct answer.'),
25
+ })
26
+ ),
27
+ })
28
+ ),
29
+ });
30
+
31
+ export const quizOptionExplanationSchema = z.object({
32
+ explanation: z
33
+ .string()
34
+ .describe(
35
+ 'Explain why this option is correct or incorrect, if it is incorrect, explain possible misconceptions and what made the option wrong with respect to the question, if it is correct, explain why it is correct. Be as detailed as possible.'
36
+ ),
37
+ });
38
+
39
+ export const quickJournalTaskSchema = z.object({
40
+ tasks: z
41
+ .array(
42
+ z.object({
43
+ title: z
44
+ .string()
45
+ .min(1)
46
+ .max(120)
47
+ .describe('Concise, action-oriented title for the task'),
48
+ description: z
49
+ .string()
50
+ .max(4000)
51
+ .optional()
52
+ .describe(
53
+ 'Optional summary of the task with actionable next steps when requested'
54
+ ),
55
+ priority: z
56
+ .enum(['critical', 'high', 'normal', 'low'])
57
+ .optional()
58
+ .describe('Relative urgency for the task'),
59
+ labelSuggestions: z
60
+ .array(
61
+ z
62
+ .string()
63
+ .min(1)
64
+ .max(48)
65
+ .describe('Short keyword or phrase recommended as a label')
66
+ )
67
+ .max(6)
68
+ .optional()
69
+ .describe('Suggested labels that align with the task content'),
70
+ dueDate: z
71
+ .string()
72
+ .optional()
73
+ .describe(
74
+ 'ISO 8601 date (YYYY-MM-DD) when an explicit due date is mentioned; omit otherwise'
75
+ ),
76
+ })
77
+ )
78
+ .min(1)
79
+ .max(50)
80
+ .describe('List of actionable tasks derived from the journal entry'),
81
+ });
82
+
83
+ const resourceSchema = z.object({
84
+ title: z.string().describe('Title of the resource'),
85
+ url: z.string().describe('URL or link to the resource'),
86
+ type: z
87
+ .enum(['video', 'article', 'book', 'course', 'other'])
88
+ .describe('Type of resource'),
89
+ });
90
+
91
+ const taskSchema = z.object({
92
+ title: z.string().describe('Title of the task'),
93
+ description: z
94
+ .string()
95
+ .describe('Detailed description of what needs to be done'),
96
+ priority: z
97
+ .enum(['high', 'medium', 'low'])
98
+ .describe('Priority level of the task'),
99
+ start_date: z.string().describe('Start date of the task (ISO date string)'),
100
+ end_date: z.string().describe('End date of the task (ISO date string)'),
101
+ status: z
102
+ .enum(['not-started', 'in-progress', 'completed', 'blocked'])
103
+ .describe('Current status of the task'),
104
+ estimatedHours: z
105
+ .number()
106
+ .min(0)
107
+ .describe('Estimated hours to complete the task'),
108
+ // dependencies: z
109
+ // .array(z.string())
110
+ // .optional()
111
+ // .describe('List of dependencies for this task'),
112
+ resources: z
113
+ .array(resourceSchema)
114
+ .optional()
115
+ .describe('Learning resources for this task'),
116
+ });
117
+
118
+ const milestoneSchema = z.object({
119
+ title: z.string().describe('Title of the milestone'),
120
+ description: z
121
+ .string()
122
+ .describe('Detailed description of what needs to be achieved'),
123
+ start_date: z
124
+ .string()
125
+ .describe('Start date of the milestone (ISO date string)'),
126
+ end_date: z.string().describe('End date of the milestone (ISO date string)'),
127
+ tasks: z.array(taskSchema).describe('List of tasks for this milestone'),
128
+ // progress: z
129
+ // .number()
130
+ // .min(0)
131
+ // .max(100)
132
+ // .describe('Progress percentage of the milestone'),
133
+ // objectives: z
134
+ // .array(z.string())
135
+ // .describe('Learning objectives for this milestone'),
136
+ // keyOutcomes: z
137
+ // .array(z.string())
138
+ // .describe('Key outcomes expected from this milestone'),
139
+ });
140
+
141
+ const quarterSchema = z.object({
142
+ quarter: z.number().min(1).max(4).describe('Quarter number (1-4)'),
143
+ focus: z.string().describe('Main focus and objectives for this quarter'),
144
+ milestones: z
145
+ .array(milestoneSchema)
146
+ .describe('List of milestones for this quarter'),
147
+ start_date: z
148
+ .string()
149
+ .describe('Start date of the quarter (ISO date string)'),
150
+ end_date: z.string().describe('End date of the quarter (ISO date string)'),
151
+ // learningObjectives: z
152
+ // .array(z.string())
153
+ // .describe('Learning objectives for this quarter'),
154
+ // expectedOutcomes: z
155
+ // .array(z.string())
156
+ // .describe('Expected outcomes for this quarter'),
157
+ // progress: z
158
+ // .number()
159
+ // .min(0)
160
+ // .max(100)
161
+ // .optional()
162
+ // .describe('Progress percentage of the quarter'),
163
+ });
164
+
165
+ export const yearPlanSchema = z.object({
166
+ yearPlan: z.object({
167
+ overview: z
168
+ .string()
169
+ .describe(
170
+ 'A high-level overview of the year plan and how the goals will be achieved'
171
+ ),
172
+ quarters: z
173
+ .array(quarterSchema)
174
+ .describe('List of quarters in the year plan'),
175
+ recommendations: z
176
+ .array(z.string())
177
+ .describe('Additional recommendations, tips, or considerations'),
178
+ start_date: z
179
+ .string()
180
+ .describe('Start date of the year plan (ISO date string)'),
181
+ end_date: z
182
+ .string()
183
+ .describe('End date of the year plan (ISO date string)'),
184
+ // metadata: metadataSchema.describe('Additional metadata about the plan'),
185
+ // progress: progressSchema.describe('Overall progress tracking'),
186
+ }),
187
+ });