feat: ditch triplit, move to postgresql + drizzle orm

This commit is contained in:
Zoe
2026-04-08 17:03:07 -05:00
parent c341c96798
commit e2e3ac6e86
121 changed files with 6680 additions and 4373 deletions
+13 -14
View File
@@ -1,14 +1,11 @@
<script setup lang="ts">
import type { BaseMessage } from '~/composables/useChat';
import { onMounted, ref, watch, onUnmounted, nextTick, type Ref } from 'vue';
import { nanoid } from 'nanoid';
import { assert } from '~~/utils/assert';
import type { ModelWithProvider, ProviderWithModels } from '~/composables/useModels';
import type { Agent } from '~/composables/useAgents';
import type FileSelector from './FileSelector.vue';
const { allModels } = useModels();
const { user } = useAuth();
const { allModels } = await useModels();
const inputHeight: Ref<string> = ref('auto');
const fileSelectorRef = ref<InstanceType<typeof FileSelector> | null>(null);
@@ -30,7 +27,6 @@ watch(textAreaValue, (newValue) => {
watch(files, (newFiles) => {
inputValue.value.fileIds = newFiles.map(f => f.id);
});
const triplit = useTriplitClient();
const emit = defineEmits<{
submit: [value: BaseMessage, model: ModelWithProvider | null];
@@ -39,7 +35,7 @@ const emit = defineEmits<{
const props = defineProps<{
loading?: boolean;
agent: Agent | null;
agent: Readonly<Agent> | null;
providers?: ProviderWithModels[];
}>();
@@ -82,8 +78,11 @@ const initializeModel = () => {
const updateAgentDefaultModel = async (modelId: string) => {
if (!props.agent) return;
try {
await triplit.update('agents', props.agent.id, (agent) => {
agent.defaultModelId = modelId;
await $fetch(`/api/agent/${props.agent.id}`, {
method: 'PATCH',
body: {
defaultModelId: modelId,
},
});
} catch (error) {
console.error('Failed to update agent default model:', error);
@@ -114,8 +113,8 @@ const handleSubmit = () => {
}
if (inputValue.value.content.trim() || inputValue.value.fileIds.length > 0) {
emit('submit', inputValue.value, selectedModel.value);
inputValue.value = { content: '', fileIds: [] };
emit('submit', structuredClone(toRaw(inputValue.value)), selectedModel.value);
files.value = [];
textAreaValue.value = '';
}
// Reset height after sending
@@ -225,12 +224,12 @@ onUnmounted(() => {
<textarea data-gramm="false" id="chat" v-model="textAreaValue" ref="inputRef"
:placeholder="`Start something great. Press ${hasCommandKey ? '⌘ + Enter' : 'ctrl + Enter'} to insert a new line.`"
@keydown="handleKeyDown" :style="{ height: inputHeight }"
class="[scrollbar-width:none] w-full bg-transparent resize-none text-[0.95em] placeholder:text-[var(--text-tertiary)]"></textarea>
class="[scrollbar-width:none] w-full bg-transparent resize-none placeholder:text-[var(--text-tertiary)]"></textarea>
</div>
<div class="flex items-center justify-between gap-2">
<!-- TODO: since we dont want to model selector dropdown to potentially overflow, it has max-width: 100%, so, we need to maake the trigger large enough to fit the entire width of the dropdown -->
<div class="flex flex-1 gap-1">
<div class="flex flex-1 gap-1 min-w-0">
<ModelSelector v-if="providers !== undefined" :add-hotkey="true" v-model="selectedModel"
:providers="providers" />
<FileSelector ref="fileSelectorRef" :selected-model="selectedModel" v-model="files" />
@@ -239,9 +238,9 @@ onUnmounted(() => {
:disabled="(!inputValue.content.trim() && files.length === 0) && !loading" :class="[
'h-8 w-8 rounded-xl transition-all duration-200 flex items-center justify-center disabled:cursor-not-allowed disabled:bg-transparent',
(inputValue.content.trim() || files.length > 0) && !loading
? 'bg-[var(--color-accent)] text-[var(--color-accent-text)] hover:bg-[var(--color-accent-hover)]'
? 'bg-[var(--color-accent)] text-[var(--color-accent-text)] @hover:bg-[var(--color-accent-hover)]'
: 'text-[var(--text-dim)]',
loading && 'bg-[var(--color-hover)] hover:bg-[var(--color-active)]',
loading && 'bg-[var(--color-hover)] @hover:bg-[var(--color-active)]',
]">
<span v-if="loading" class="text-6.5 i-mynaui-stop-solid"></span>
<span v-else class="text-5 i-mynaui-send-solid"></span>