@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,74 @@
1
+ import { z } from 'zod';
2
+ import { tool } from '../core';
3
+
4
+ const hexColorSchema = z
5
+ .string()
6
+ .trim()
7
+ .regex(/^#(?:[0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/)
8
+ .optional();
9
+ const qrPayloadSchema = z.string().trim().min(1).max(4096);
10
+
11
+ export const imageToolDefinitions = {
12
+ create_image: tool({
13
+ description: 'Generate an image from a text description.',
14
+ inputSchema: z.object({
15
+ prompt: z.string().describe('Detailed image description'),
16
+ aspectRatio: z
17
+ .enum(['1:1', '3:4', '4:3', '9:16', '16:9'])
18
+ .optional()
19
+ .describe('Aspect ratio (default 1:1)'),
20
+ model: z
21
+ .enum([
22
+ 'google/imagen-4.0-fast-generate-001',
23
+ 'google/imagen-4.0-generate-001',
24
+ 'google/gemini-2.5-flash-image',
25
+ ])
26
+ .optional()
27
+ .describe('Image model (auto-selected by plan if omitted)'),
28
+ }),
29
+ }),
30
+ create_qr_code: tool({
31
+ description:
32
+ 'Generate a QR code image from any text payload and save it to workspace Drive storage.',
33
+ inputSchema: z
34
+ .object({
35
+ value: qrPayloadSchema
36
+ .optional()
37
+ .describe('Text content to encode into the QR code'),
38
+ text: qrPayloadSchema
39
+ .optional()
40
+ .describe('Alias for value when the user provides plain text'),
41
+ url: qrPayloadSchema
42
+ .optional()
43
+ .describe('Alias for value when the user provides a URL'),
44
+ foregroundColor: hexColorSchema.describe(
45
+ 'QR foreground color in hex, e.g. #000000'
46
+ ),
47
+ backgroundColor: hexColorSchema.describe(
48
+ 'QR background color in hex, e.g. #FFFFFF'
49
+ ),
50
+ size: z
51
+ .number()
52
+ .int()
53
+ .min(128)
54
+ .max(2048)
55
+ .optional()
56
+ .describe('Image width/height in pixels (default 512)'),
57
+ fileName: z
58
+ .string()
59
+ .trim()
60
+ .min(1)
61
+ .max(120)
62
+ .regex(
63
+ /^[A-Za-z0-9._ -]+$/,
64
+ 'Filename may only include letters, numbers, spaces, dot, underscore, and hyphen.'
65
+ )
66
+ .optional()
67
+ .describe('Optional desired filename for download and storage'),
68
+ })
69
+ .refine((input) => input.value || input.text || input.url, {
70
+ message: 'Provide value, text, or url to encode into the QR code.',
71
+ path: ['value'],
72
+ }),
73
+ }),
74
+ } as const;
@@ -0,0 +1,83 @@
1
+ import { z } from 'zod';
2
+ import { tool } from '../core';
3
+
4
+ export const MIRA_MEMORY_CATEGORIES = [
5
+ 'preference',
6
+ 'fact',
7
+ 'conversation_topic',
8
+ 'event',
9
+ 'person',
10
+ ] as const;
11
+
12
+ export type MiraMemoryCategory = (typeof MIRA_MEMORY_CATEGORIES)[number];
13
+
14
+ export const MEMORY_CATEGORY = z.enum(MIRA_MEMORY_CATEGORIES);
15
+
16
+ export const memoryToolDefinitions = {
17
+ remember: tool({
18
+ description:
19
+ 'Save a memory or fact about the user. Store rich, contextual values. For people use key format person_<name>.',
20
+ inputSchema: z.object({
21
+ key: z
22
+ .string()
23
+ .describe('Short label (e.g. "user_birthday", "person_quoc")'),
24
+ value: z.string().describe('Detailed contextual content to remember'),
25
+ category: MEMORY_CATEGORY.describe('Memory category'),
26
+ }),
27
+ }),
28
+
29
+ recall: tool({
30
+ description:
31
+ 'Search saved memories. Pass null query with high maxResults for "everything" requests.',
32
+ inputSchema: z.object({
33
+ query: z
34
+ .string()
35
+ .nullish()
36
+ .describe('Search keywords, or null/omit for all'),
37
+ category: MEMORY_CATEGORY.nullish().describe(
38
+ 'Filter by category, or null/omit'
39
+ ),
40
+ maxResults: z
41
+ .number()
42
+ .int()
43
+ .min(1)
44
+ .max(50)
45
+ .optional()
46
+ .describe(
47
+ 'Max results (default: 10, use 20-50 for broad queries, 5-10 for specific)'
48
+ ),
49
+ }),
50
+ }),
51
+
52
+ delete_memory: tool({
53
+ description: 'Delete a single memory by its exact key.',
54
+ inputSchema: z.object({
55
+ key: z.string().describe('The exact key of the memory to delete'),
56
+ }),
57
+ }),
58
+
59
+ list_memories: tool({
60
+ description:
61
+ 'List all stored memories, optionally filtered by category. Used for memory hygiene and review.',
62
+ inputSchema: z.object({
63
+ category: MEMORY_CATEGORY.nullish().describe(
64
+ 'Category to filter memories by'
65
+ ),
66
+ }),
67
+ }),
68
+
69
+ merge_memories: tool({
70
+ description:
71
+ 'Consolidate multiple existing memories into a single new memory. The old memories will be deleted.',
72
+ inputSchema: z.object({
73
+ keysToDelete: z
74
+ .array(z.string())
75
+ .describe('Array of exact keys to delete'),
76
+ newKey: z.string().describe('The key for the new consolidated memory'),
77
+ newValue: z
78
+ .string()
79
+ .describe('The value for the new consolidated memory'),
80
+ newCategory: MEMORY_CATEGORY.describe('Category for the new memory'),
81
+ }),
82
+ }),
83
+ } as const;
@@ -0,0 +1,154 @@
1
+ import { z } from 'zod';
2
+ import { tool } from '../core';
3
+ import { MIRA_TOOL_NAMES } from '../mira-tool-names';
4
+
5
+ const validToolSet = new Set<string>(MIRA_TOOL_NAMES);
6
+
7
+ const requiredTrimmedString = (max: number, field: string) =>
8
+ z.preprocess(
9
+ (value) => (typeof value === 'string' ? value.trim() : value),
10
+ z.string().min(1, `${field} cannot be blank`).max(max)
11
+ );
12
+
13
+ const optionalTrimmedString = (max: number, field: string) =>
14
+ z.preprocess(
15
+ (value) => (typeof value === 'string' ? value.trim() : value),
16
+ z.string().min(1, `${field} cannot be blank`).max(max).optional()
17
+ );
18
+
19
+ export const metaToolDefinitions = {
20
+ select_tools: tool({
21
+ description:
22
+ 'Pick which tools you need for this request. You may stream a short text acknowledgement first when useful, then call this before using other Mira tools. Choose from the available tool names listed in the system prompt. Use no_action_needed ONLY for truly conversational turns with no durable info to save and no real-world lookup needed.',
23
+ inputSchema: z.object({
24
+ tools: z
25
+ .array(z.string())
26
+ .min(1)
27
+ .refine(
28
+ (tools) => tools.every((toolName) => validToolSet.has(toolName)),
29
+ {
30
+ message: 'Invalid tool name(s)',
31
+ }
32
+ )
33
+ .refine((tools) => new Set(tools).size === tools.length, {
34
+ message: 'Duplicate tools are not allowed',
35
+ })
36
+ .refine(
37
+ (tools) => !tools.includes('no_action_needed') || tools.length === 1,
38
+ {
39
+ message: 'no_action_needed must be selected by itself',
40
+ }
41
+ )
42
+ .describe(
43
+ 'Array of tool names to activate (e.g. ["get_my_tasks", "create_task"]). Include all tools you expect to call.'
44
+ ),
45
+ }),
46
+ }),
47
+
48
+ no_action_needed: tool({
49
+ description:
50
+ 'Call only when the message is purely conversational and requires NO real action (no settings/memory updates, no search, no data/tool operation).',
51
+ inputSchema: z.object({
52
+ reason: z
53
+ .string()
54
+ .trim()
55
+ .min(1, 'reason cannot be blank')
56
+ .describe('Brief reason (e.g. "user said thanks")'),
57
+ }),
58
+ }),
59
+
60
+ google_search: tool({
61
+ description:
62
+ 'Search the public web for current, real-time information such as news, pricing, weather, and up-to-date facts.',
63
+ inputSchema: z.object({
64
+ query: requiredTrimmedString(500, 'query').describe(
65
+ 'Search query for web lookup'
66
+ ),
67
+ }),
68
+ }),
69
+
70
+ run_parallel_checks: tool({
71
+ description:
72
+ 'Run lightweight parallel subagents for complex verification, planning, risk review, or conflicting-assumption checks. Use this for explicit deep verification requests instead of enabling main-assistant reasoning by default.',
73
+ inputSchema: z.object({
74
+ question: requiredTrimmedString(2000, 'question').describe(
75
+ 'The exact question, plan, claim, or scenario to verify.'
76
+ ),
77
+ context: z
78
+ .string()
79
+ .trim()
80
+ .max(8000)
81
+ .optional()
82
+ .describe(
83
+ 'Optional relevant context from the conversation or tool results.'
84
+ ),
85
+ checks: z
86
+ .array(z.enum(['assumptions', 'factuality', 'risk', 'implementation']))
87
+ .min(1)
88
+ .max(4)
89
+ .optional()
90
+ .describe(
91
+ 'Optional focused checks to run in parallel. Defaults to assumptions, factuality, and risk.'
92
+ ),
93
+ }),
94
+ toModelOutput: ({ output }) => {
95
+ if (!output || typeof output !== 'object') {
96
+ return { type: 'text', value: 'Parallel checks completed.' };
97
+ }
98
+
99
+ const result = output as {
100
+ ok?: boolean;
101
+ summary?: string;
102
+ checks?: Array<{ label?: string; finding?: string }>;
103
+ error?: string;
104
+ };
105
+
106
+ if (result.ok === false) {
107
+ return {
108
+ type: 'text',
109
+ value: result.error ?? 'Parallel checks failed.',
110
+ };
111
+ }
112
+
113
+ const checkLines =
114
+ result.checks
115
+ ?.map((check) =>
116
+ check.label && check.finding
117
+ ? `- ${check.label}: ${check.finding}`
118
+ : null
119
+ )
120
+ .filter((line): line is string => line !== null)
121
+ .join('\n') ?? '';
122
+
123
+ return {
124
+ type: 'text',
125
+ value: [result.summary, checkLines].filter(Boolean).join('\n'),
126
+ };
127
+ },
128
+ }),
129
+
130
+ convert_file_to_markdown: tool({
131
+ description:
132
+ 'Convert an attached chat file (Excel, Word, PowerPoint, PDF, etc.) to markdown via MarkItDown. Do not use this for YouTube links; Google/Gemini models receive YouTube URLs as native video input.',
133
+ inputSchema: z.object({
134
+ url: optionalTrimmedString(2048, 'url').describe(
135
+ 'Deprecated. Do not use for YouTube summaries; the chat request pipeline attaches YouTube URLs directly to Google/Gemini models as video input.'
136
+ ),
137
+ storagePath: optionalTrimmedString(1024, 'storagePath').describe(
138
+ 'Optional full storage path. If omitted, the latest file from the current chat is converted.'
139
+ ),
140
+ fileName: optionalTrimmedString(255, 'fileName').describe(
141
+ 'Optional filename from current chat attachments (for example: "report.xlsx"). Used when storagePath is not provided.'
142
+ ),
143
+ maxCharacters: z
144
+ .number()
145
+ .int()
146
+ .min(2000)
147
+ .max(300000)
148
+ .optional()
149
+ .describe(
150
+ 'Optional markdown output cap for token safety. Default is 120000.'
151
+ ),
152
+ }),
153
+ }),
154
+ } as const;
@@ -0,0 +1,81 @@
1
+ import type { FlexibleSchema } from 'ai';
2
+ import { z } from 'zod';
3
+ import { tool } from '../core';
4
+ import { dashboardCatalog } from '../json-render-catalog';
5
+ import {
6
+ createRenderUiPreprocessor,
7
+ normalizeRenderUiInputForTool,
8
+ } from '../normalize-render-ui-input';
9
+
10
+ const RENDER_UI_DESCRIPTION =
11
+ 'Render interactive UI. CRITICAL: `elements` must contain at least one entry keyed by the `root` ID. ' +
12
+ 'Example: { "root": "r", "elements": { "r": { "type": "Card", "props": { "title": "Hello" }, "children": [] } } }. ' +
13
+ 'NEVER pass empty elements ({}). Every element needs type, props, children.';
14
+
15
+ /** Base catalog Zod schema with a refinement that rejects empty `elements`. */
16
+ const baseSchemaWithRefinement = dashboardCatalog.zodSchema().refine(
17
+ (spec) => {
18
+ if (
19
+ spec &&
20
+ typeof spec === 'object' &&
21
+ 'elements' in spec &&
22
+ spec.elements &&
23
+ typeof spec.elements === 'object'
24
+ ) {
25
+ return Object.keys(spec.elements as Record<string, unknown>).length > 0;
26
+ }
27
+ return true; // Let other validators handle non-object elements.
28
+ },
29
+ {
30
+ message:
31
+ 'elements must not be empty. Define at least one element keyed by the root ID. ' +
32
+ 'Example: { "root": "r", "elements": { "r": { "type": "Card", "props": { "title": "Hello" }, "children": [] } } }',
33
+ path: ['elements'],
34
+ }
35
+ );
36
+
37
+ // AI SDK and @json-render currently expose nominal Zod minor types.
38
+ const toToolInputSchema = (schema: unknown) =>
39
+ schema as FlexibleSchema<unknown>;
40
+
41
+ /**
42
+ * Static tool definitions used for the shared tool registry.
43
+ * Uses the basic normalizer (no per-stream state).
44
+ */
45
+ export const renderUiToolDefinitions = {
46
+ render_ui: tool({
47
+ description: RENDER_UI_DESCRIPTION,
48
+ inputSchema: toToolInputSchema(
49
+ z.preprocess(
50
+ (val: unknown) => normalizeRenderUiInputForTool(val),
51
+ baseSchemaWithRefinement
52
+ )
53
+ ),
54
+ }),
55
+ } as const;
56
+
57
+ /**
58
+ * Create a render_ui tool definition with a per-stream stateful preprocessor.
59
+ *
60
+ * On the first empty-elements call, the preprocessor auto-populates a
61
+ * context-aware fallback (using data tools found in previous steps) so
62
+ * validation passes and the user sees something rather than a failure loop.
63
+ *
64
+ * @param getSteps – Optional callback returning the current steps array for
65
+ * context-aware fallback selection.
66
+ *
67
+ * Returns the tool definition and a `wasAutoPopulated()` check for the execute
68
+ * handler to detect auto-populated specs.
69
+ */
70
+ export function createStreamRenderUiTool(getSteps?: () => unknown[]) {
71
+ const { preprocess, wasAutoPopulated } = createRenderUiPreprocessor(getSteps);
72
+
73
+ const toolDef = tool({
74
+ description: RENDER_UI_DESCRIPTION,
75
+ inputSchema: toToolInputSchema(
76
+ z.preprocess((val: unknown) => preprocess(val), baseSchemaWithRefinement)
77
+ ),
78
+ });
79
+
80
+ return { toolDef, wasAutoPopulated };
81
+ }