diff --git a/app/(chat)/api/chat/route.ts b/app/(chat)/api/chat/route.ts index 81d024e..9c6a84f 100644 --- a/app/(chat)/api/chat/route.ts +++ b/app/(chat)/api/chat/route.ts @@ -18,7 +18,6 @@ import { saveChat, saveMessages, } from '@/lib/db/queries'; -import { updateChatLastContextById } from '@/lib/db/queries'; import { convertToUIMessages, generateUUID } from '@/lib/utils'; import { generateTitleFromUserMessage } from '../../actions'; import { createDocument } from '@/lib/ai/tools/create-document'; @@ -209,17 +208,6 @@ export async function POST(request: Request) { chatId: id, })), }); - - if (finalUsage) { - try { - await updateChatLastContextById({ - chatId: id, - context: finalUsage, - }); - } catch (err) { - console.warn('Unable to persist last usage for chat', id, err); - } - } }, onError: () => { return 'Oops, an error occurred!'; diff --git a/app/(chat)/chat/[id]/page.tsx b/app/(chat)/chat/[id]/page.tsx index e2e7c37..b9dc99d 100644 --- a/app/(chat)/chat/[id]/page.tsx +++ b/app/(chat)/chat/[id]/page.tsx @@ -7,7 +7,6 @@ import { getChatById, getMessagesByChatId } from '@/lib/db/queries'; import { DataStreamHandler } from '@/components/data-stream-handler'; import { DEFAULT_CHAT_MODEL } from '@/lib/ai/models'; import { convertToUIMessages } from '@/lib/utils'; -import { LanguageModelV2Usage } from '@ai-sdk/provider'; export default async function Page(props: { params: Promise<{ id: string }> }) { const params = await props.params; @@ -54,7 +53,6 @@ export default async function Page(props: { params: Promise<{ id: string }> }) { isReadonly={session?.user?.id !== chat.userId} session={session} autoResume={true} - initialLastContext={chat.lastContext} /> @@ -71,7 +69,6 @@ export default async function Page(props: { params: Promise<{ id: string }> }) { isReadonly={session?.user?.id !== chat.userId} session={session} autoResume={true} - initialLastContext={chat.lastContext} /> diff --git a/components/chat.tsx b/components/chat.tsx index 43b0159..711616f 100644 --- a/components/chat.tsx +++ b/components/chat.tsx @@ -31,7 +31,6 @@ export function Chat({ isReadonly, session, autoResume, - initialLastContext, }: { id: string; initialMessages: ChatMessage[]; @@ -40,7 +39,6 @@ export function Chat({ isReadonly: boolean; session: Session; autoResume: boolean; - initialLastContext?: LanguageModelUsage; }) { const { visibilityType } = useChatVisibility({ chatId: id, @@ -51,9 +49,7 @@ export function Chat({ const { setDataStream } = useDataStream(); const [input, setInput] = useState(''); - const [usage, setUsage] = useState( - initialLastContext, - ); + const [usage, setUsage] = useState(undefined); const { messages, diff --git a/components/elements/context.tsx b/components/elements/context.tsx index dd7cf4f..ea938a8 100644 --- a/components/elements/context.tsx +++ b/components/elements/context.tsx @@ -10,7 +10,6 @@ import type { ComponentProps } from 'react'; import type { LanguageModelUsage } from 'ai'; import { breakdownTokens, estimateCost, normalizeUsage } from 'tokenlens'; import { Separator } from '@/components/ui/separator'; -import { Progress } from '@/components/ui/progress'; export type ContextProps = ComponentProps<'button'> & { /** Total context window size in tokens */ @@ -21,6 +20,8 @@ export type ContextProps = ComponentProps<'button'> & { usage?: LanguageModelUsage | undefined; /** Optional model id (canonical or alias) to compute cost */ modelId?: string; + /** Show token breakdown and optional cost inside hover */ + showBreakdown?: boolean; }; const THOUSAND = 1000; @@ -80,11 +81,6 @@ const formatUSD = (value?: number) => { return `$${trimmed}`; }; -const formatUSDFixed = (value?: number, decimals = 5) => { - if (value === undefined || !Number.isFinite(value)) return undefined; - return `$${Number(value).toFixed(decimals)}`; -}; - type ContextIconProps = { percent: number; // 0 - 100 }; @@ -129,46 +125,13 @@ export const ContextIcon = ({ percent }: ContextIconProps) => { ); }; -function TokensWithCost({ - tokens, - costText, -}: { - tokens?: number; - costText?: string; -}) { - return ( - - {tokens === undefined ? '—' : formatTokens(tokens)} - {costText ? ( - • {costText} - ) : null} - - ); -} - -function InfoRow({ - label, - tokens, - costText, -}: { - label: string; - tokens?: number; - costText?: string; -}) { - return ( -
- {label} - -
- ); -} - export const Context = ({ className, maxTokens, usedTokens, usage, modelId, + showBreakdown, ...props }: ContextProps) => { const safeMax = Math.max(0, Number.isFinite(maxTokens) ? maxTokens : 0); @@ -176,105 +139,38 @@ export const Context = ({ Math.max(0, Number.isFinite(usedTokens) ? usedTokens : 0), safeMax, ); - - // used percent and used tokens to display (demo-aware) - const displayUsedTokens = safeUsed; const usedPercent = safeMax > 0 - ? Math.min( - PERCENT_MAX, - Math.max(0, (displayUsedTokens / safeMax) * PERCENT_MAX), - ) + ? Math.min(PERCENT_MAX, Math.max(0, (safeUsed / safeMax) * PERCENT_MAX)) : 0; const displayPct = formatPercent(Math.round(usedPercent * 10) / 10); - const used = formatTokens(displayUsedTokens); + const used = formatTokens(safeUsed); const total = formatTokens(safeMax); - const uNorm = normalizeUsage(usage); - const uBreakdown = breakdownTokens(usage); - - const hasUsage = - !!usage && - ((uNorm.input ?? 0) > 0 || - (uNorm.output ?? 0) > 0 || - (uBreakdown.cacheReads ?? 0) > 0 || - (uBreakdown.cacheWrites ?? 0) > 0 || - (uBreakdown.reasoningTokens ?? 0) > 0); - - // Values to render in rows (demo or real) - const displayInput = uNorm.input; - const displayOutput = uNorm.output; - - // Per-segment costs - const inputCostText = modelId - ? formatUSDFixed( - estimateCost({ - modelId, - usage: { input: displayInput ?? 0, output: 0 }, - }).inputUSD, - ) - : undefined; - const outputCostText = modelId - ? formatUSDFixed( - estimateCost({ - modelId, - usage: { input: 0, output: displayOutput ?? 0 }, - }).outputUSD, - ) - : undefined; - // Not supported by tokenlens pricing hints; leave undefined so no bullet is shown - const cacheReadsTokens = uBreakdown.cacheReads ?? 0; - const cacheWritesTokens = uBreakdown.cacheWrites ?? 0; - const cacheReadsCostText = - modelId && cacheReadsTokens > 0 - ? formatUSDFixed( - estimateCost({ - modelId, - // Cast to any to support extended pricing fields provided by tokenlens - usage: { cacheReads: cacheReadsTokens } as any, - }).totalUSD, - ) - : undefined; - const cacheWritesCostText = - modelId && cacheWritesTokens > 0 - ? formatUSDFixed( - estimateCost({ - modelId, - usage: { cacheWrites: cacheWritesTokens } as any, - }).totalUSD, - ) - : undefined; - - const reasoningTokens = uBreakdown.reasoningTokens ?? 0; - const reasoningCostText = - modelId && reasoningTokens > 0 - ? formatUSDFixed( - estimateCost({ - modelId, - usage: { reasoningTokens }, - }).totalUSD, - ) - : undefined; - + const uNorm = normalizeUsage(usage as any); + const uBreakdown = breakdownTokens(usage as any); const costUSD = modelId - ? estimateCost({ - modelId, - usage: { input: displayInput ?? 0, output: displayOutput ?? 0 }, - }).totalUSD + ? estimateCost({ modelId, usage: uNorm }).totalUSD : undefined; - const costText = formatUSDFixed(costUSD); + const costText = formatUSD(costUSD); + const segInput = Math.max(0, uNorm.input ?? 0); + const segOutput = Math.max(0, uNorm.output ?? 0); + const segCacheR = Math.max(0, uBreakdown.cacheReads ?? 0); + const segCacheW = Math.max(0, uBreakdown.cacheWrites ?? 0); + const denom = safeMax > 0 ? safeMax : 1; + const w = (n: number) => + `${Math.min(100, Math.max(0, (n / denom) * 100)).toFixed(2)}%`; const fmtOrUnknown = (n?: number) => n === undefined ? '—' : formatTokens(n); - return ( - +
-

+

{displayPct} • {used} / {total} tokens + {costText ? ( + • {costText} + ) : null}

-
- -
-
- {hasUsage && uBreakdown.cacheReads && uBreakdown.cacheReads > 0 && ( - - )} - {hasUsage && - uBreakdown.cacheWrites && - uBreakdown.cacheWrites > 0 && ( - +
+
- )} - - - 0 ? reasoningTokens : undefined} - costText={reasoningCostText} - /> - {costText && ( - <> - -
- Total cost - {costText} +
+
+
+
+
+
+ + + Cache Hits + + {fmtOrUnknown(uBreakdown.cacheReads)}
- - )} -
+
+ + + Cache Writes + + {fmtOrUnknown(uBreakdown.cacheWrites)} +
+
+ + + Input + + {formatTokens(uNorm.input)} +
+
+ + + Output + + {formatTokens(uNorm.output)} +
+
+
+ )} + {showBreakdown && ( +
+
+ Cache Hits + {fmtOrUnknown(uBreakdown.cacheReads)} +
+
+ Cache Writes + {fmtOrUnknown(uBreakdown.cacheWrites)} +
+
+ Input + {formatTokens(uNorm.input)} +
+
+ Output + {formatTokens(uNorm.output)} +
+ {costText && ( + <> + +
+ Total cost + {costText} +
+ + )} +
+ )}
diff --git a/components/multimodal-input.tsx b/components/multimodal-input.tsx index 21c9f4d..cedf253 100644 --- a/components/multimodal-input.tsx +++ b/components/multimodal-input.tsx @@ -214,6 +214,7 @@ function PureMultimodalInput({ usedTokens, usage, modelId: modelResolver.modelId, + showBreakdown: true as const, }), [contextMax, usedTokens, usage, modelResolver], ); @@ -342,22 +343,20 @@ function PureMultimodalInput({ ))}
)} -
- {' '} - -
+ + + - {status === 'submitted' ? ( ) : ( diff --git a/components/ui/progress.tsx b/components/ui/progress.tsx deleted file mode 100644 index 5c87ea4..0000000 --- a/components/ui/progress.tsx +++ /dev/null @@ -1,28 +0,0 @@ -"use client" - -import * as React from "react" -import * as ProgressPrimitive from "@radix-ui/react-progress" - -import { cn } from "@/lib/utils" - -const Progress = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, value, ...props }, ref) => ( - - - -)) -Progress.displayName = ProgressPrimitive.Root.displayName - -export { Progress } diff --git a/lib/db/migrations/0007_flowery_ben_parker.sql b/lib/db/migrations/0007_flowery_ben_parker.sql deleted file mode 100644 index 163f0d0..0000000 --- a/lib/db/migrations/0007_flowery_ben_parker.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE "Chat" ADD COLUMN "lastContext" jsonb; \ No newline at end of file diff --git a/lib/db/migrations/meta/0007_snapshot.json b/lib/db/migrations/meta/0007_snapshot.json deleted file mode 100644 index 31dfedf..0000000 --- a/lib/db/migrations/meta/0007_snapshot.json +++ /dev/null @@ -1,571 +0,0 @@ -{ - "id": "097660a7-976a-4b3e-8ebb-79312e3ece6f", - "prevId": "443de550-b7e8-4bfb-b229-c12dc6c132f0", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.Chat": { - "name": "Chat", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp", - "primaryKey": false, - "notNull": true - }, - "title": { - "name": "title", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "userId": { - "name": "userId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "visibility": { - "name": "visibility", - "type": "varchar", - "primaryKey": false, - "notNull": true, - "default": "'private'" - }, - "lastContext": { - "name": "lastContext", - "type": "jsonb", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "Chat_userId_User_id_fk": { - "name": "Chat_userId_User_id_fk", - "tableFrom": "Chat", - "tableTo": "User", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "public.Document": { - "name": "Document", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": false, - "notNull": true, - "default": "gen_random_uuid()" - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp", - "primaryKey": false, - "notNull": true - }, - "title": { - "name": "title", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "content": { - "name": "content", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "text": { - "name": "text", - "type": "varchar", - "primaryKey": false, - "notNull": true, - "default": "'text'" - }, - "userId": { - "name": "userId", - "type": "uuid", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "Document_userId_User_id_fk": { - "name": "Document_userId_User_id_fk", - "tableFrom": "Document", - "tableTo": "User", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "Document_id_createdAt_pk": { - "name": "Document_id_createdAt_pk", - "columns": [ - "id", - "createdAt" - ] - } - }, - "uniqueConstraints": {} - }, - "public.Message_v2": { - "name": "Message_v2", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "chatId": { - "name": "chatId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "role": { - "name": "role", - "type": "varchar", - "primaryKey": false, - "notNull": true - }, - "parts": { - "name": "parts", - "type": "json", - "primaryKey": false, - "notNull": true - }, - "attachments": { - "name": "attachments", - "type": "json", - "primaryKey": false, - "notNull": true - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "Message_v2_chatId_Chat_id_fk": { - "name": "Message_v2_chatId_Chat_id_fk", - "tableFrom": "Message_v2", - "tableTo": "Chat", - "columnsFrom": [ - "chatId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "public.Message": { - "name": "Message", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "chatId": { - "name": "chatId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "role": { - "name": "role", - "type": "varchar", - "primaryKey": false, - "notNull": true - }, - "content": { - "name": "content", - "type": "json", - "primaryKey": false, - "notNull": true - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "Message_chatId_Chat_id_fk": { - "name": "Message_chatId_Chat_id_fk", - "tableFrom": "Message", - "tableTo": "Chat", - "columnsFrom": [ - "chatId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "public.Stream": { - "name": "Stream", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": false, - "notNull": true, - "default": "gen_random_uuid()" - }, - "chatId": { - "name": "chatId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "Stream_chatId_Chat_id_fk": { - "name": "Stream_chatId_Chat_id_fk", - "tableFrom": "Stream", - "tableTo": "Chat", - "columnsFrom": [ - "chatId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "Stream_id_pk": { - "name": "Stream_id_pk", - "columns": [ - "id" - ] - } - }, - "uniqueConstraints": {} - }, - "public.Suggestion": { - "name": "Suggestion", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": false, - "notNull": true, - "default": "gen_random_uuid()" - }, - "documentId": { - "name": "documentId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "documentCreatedAt": { - "name": "documentCreatedAt", - "type": "timestamp", - "primaryKey": false, - "notNull": true - }, - "originalText": { - "name": "originalText", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "suggestedText": { - "name": "suggestedText", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "isResolved": { - "name": "isResolved", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "userId": { - "name": "userId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "createdAt": { - "name": "createdAt", - "type": "timestamp", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "Suggestion_userId_User_id_fk": { - "name": "Suggestion_userId_User_id_fk", - "tableFrom": "Suggestion", - "tableTo": "User", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "Suggestion_documentId_documentCreatedAt_Document_id_createdAt_fk": { - "name": "Suggestion_documentId_documentCreatedAt_Document_id_createdAt_fk", - "tableFrom": "Suggestion", - "tableTo": "Document", - "columnsFrom": [ - "documentId", - "documentCreatedAt" - ], - "columnsTo": [ - "id", - "createdAt" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "Suggestion_id_pk": { - "name": "Suggestion_id_pk", - "columns": [ - "id" - ] - } - }, - "uniqueConstraints": {} - }, - "public.User": { - "name": "User", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "email": { - "name": "email", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "password": { - "name": "password", - "type": "varchar(64)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "public.Vote_v2": { - "name": "Vote_v2", - "schema": "", - "columns": { - "chatId": { - "name": "chatId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "messageId": { - "name": "messageId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "isUpvoted": { - "name": "isUpvoted", - "type": "boolean", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "Vote_v2_chatId_Chat_id_fk": { - "name": "Vote_v2_chatId_Chat_id_fk", - "tableFrom": "Vote_v2", - "tableTo": "Chat", - "columnsFrom": [ - "chatId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "Vote_v2_messageId_Message_v2_id_fk": { - "name": "Vote_v2_messageId_Message_v2_id_fk", - "tableFrom": "Vote_v2", - "tableTo": "Message_v2", - "columnsFrom": [ - "messageId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "Vote_v2_chatId_messageId_pk": { - "name": "Vote_v2_chatId_messageId_pk", - "columns": [ - "chatId", - "messageId" - ] - } - }, - "uniqueConstraints": {} - }, - "public.Vote": { - "name": "Vote", - "schema": "", - "columns": { - "chatId": { - "name": "chatId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "messageId": { - "name": "messageId", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "isUpvoted": { - "name": "isUpvoted", - "type": "boolean", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "Vote_chatId_Chat_id_fk": { - "name": "Vote_chatId_Chat_id_fk", - "tableFrom": "Vote", - "tableTo": "Chat", - "columnsFrom": [ - "chatId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "Vote_messageId_Message_id_fk": { - "name": "Vote_messageId_Message_id_fk", - "tableFrom": "Vote", - "tableTo": "Message", - "columnsFrom": [ - "messageId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "Vote_chatId_messageId_pk": { - "name": "Vote_chatId_messageId_pk", - "columns": [ - "chatId", - "messageId" - ] - } - }, - "uniqueConstraints": {} - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/lib/db/migrations/meta/_journal.json b/lib/db/migrations/meta/_journal.json index e907731..f7b8875 100644 --- a/lib/db/migrations/meta/_journal.json +++ b/lib/db/migrations/meta/_journal.json @@ -50,13 +50,6 @@ "when": 1746118166211, "tag": "0006_marvelous_frog_thor", "breakpoints": true - }, - { - "idx": 7, - "version": "7", - "when": 1757362773211, - "tag": "0007_flowery_ben_parker", - "breakpoints": true } ] } \ No newline at end of file diff --git a/lib/db/queries.ts b/lib/db/queries.ts index 958b24e..2f8b2b2 100644 --- a/lib/db/queries.ts +++ b/lib/db/queries.ts @@ -33,7 +33,6 @@ import { generateUUID } from '../utils'; import { generateHashedPassword } from './utils'; import type { VisibilityType } from '@/components/visibility-selector'; import { ChatSDKError } from '../errors'; -import { LanguageModelV2Usage } from '@ai-sdk/provider'; // Optionally, if not using email/pass login, you can // use the Drizzle adapter for Auth.js / NextAuth @@ -203,10 +202,7 @@ export async function getChatsByUserId({ export async function getChatById({ id }: { id: string }) { try { const [selectedChat] = await db.select().from(chat).where(eq(chat.id, id)); - return { - ...selectedChat, - lastContext: selectedChat.lastContext as LanguageModelV2Usage, - }; + return selectedChat; } catch (error) { throw new ChatSDKError('bad_request:database', 'Failed to get chat by id'); } @@ -473,32 +469,10 @@ export async function updateChatVisiblityById({ } } -export async function updateChatLastContextById({ - chatId, - context, -}: { - chatId: string; - // Store raw LanguageModelUsage to keep it simple - context: LanguageModelV2Usage; -}) { - try { - return await db - .update(chat) - .set({ lastContext: context as any }) - .where(eq(chat.id, chatId)); - } catch (error) { - console.warn('Failed to update lastContext for chat', chatId, error); - return; - } -} - export async function getMessageCountByUserId({ id, differenceInHours, -}: { - id: string; - differenceInHours: number; -}) { +}: { id: string; differenceInHours: number }) { try { const twentyFourHoursAgo = new Date( Date.now() - differenceInHours * 60 * 60 * 1000, diff --git a/lib/db/schema.ts b/lib/db/schema.ts index 14a0436..8f9256b 100644 --- a/lib/db/schema.ts +++ b/lib/db/schema.ts @@ -4,7 +4,6 @@ import { varchar, timestamp, json, - jsonb, uuid, text, primaryKey, @@ -30,7 +29,6 @@ export const chat = pgTable('Chat', { visibility: varchar('visibility', { enum: ['public', 'private'] }) .notNull() .default('private'), - lastContext: jsonb('lastContext'), }); export type Chat = InferSelectModel; diff --git a/package.json b/package.json index 0207d2c..ca3118f 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,6 @@ "@radix-ui/react-hover-card": "^1.1.15", "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-label": "^2.1.0", - "@radix-ui/react-progress": "^1.1.7", "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-select": "^2.1.2", "@radix-ui/react-separator": "^1.1.0", @@ -96,7 +95,7 @@ "swr": "^2.2.5", "tailwind-merge": "^2.5.2", "tailwindcss-animate": "^1.0.7", - "tokenlens": "^1.1.2", + "tokenlens": "^1.0.0", "use-stick-to-bottom": "^1.1.1", "usehooks-ts": "^3.1.0", "zod": "^3.25.76" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 16859f1..6c13dcc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -68,9 +68,6 @@ importers: '@radix-ui/react-label': specifier: ^2.1.0 version: 2.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021))(react@19.0.0-rc-45804af1-20241021) - '@radix-ui/react-progress': - specifier: ^1.1.7 - version: 1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021))(react@19.0.0-rc-45804af1-20241021) '@radix-ui/react-scroll-area': specifier: ^1.2.10 version: 1.2.10(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021))(react@19.0.0-rc-45804af1-20241021) @@ -240,8 +237,8 @@ importers: specifier: ^1.0.7 version: 1.0.7(tailwindcss@3.4.17) tokenlens: - specifier: ^1.1.2 - version: 1.1.2 + specifier: ^1.0.0 + version: 1.0.0 use-stick-to-bottom: specifier: ^1.1.1 version: 1.1.1(react@19.0.0-rc-45804af1-20241021) @@ -1630,19 +1627,6 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-progress@1.1.7': - resolution: {integrity: sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - '@radix-ui/react-roving-focus@1.1.2': resolution: {integrity: sha512-zgMQWkNO169GtGqRvYrzb0Zf8NhMHS2DuEB/TiEmVnpr5OqPU3i8lfbxaAmC2J/KYuIQxyoQQ6DxepyXp61/xw==} peerDependencies: @@ -4707,8 +4691,8 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - tokenlens@1.1.2: - resolution: {integrity: sha512-PICXahAiVS/2nyc30SijuYZj5wIm2G9+2U7fdvQbl5pa/hIUpQ8H+RdYOzOrSvva6GMqPM5+6cWd9Hqi81Yv3g==} + tokenlens@1.0.0: + resolution: {integrity: sha512-IslxKcdsPQv4yTUgzeAe9UoEuvXUW6BZyKvKc4N9D7IWnyUBvSTJ3hq8Wb13fM8CkgaS/0k28vpJIQiVQJrpVA==} trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} @@ -6029,16 +6013,6 @@ snapshots: '@types/react': 18.3.18 '@types/react-dom': 18.3.5(@types/react@18.3.18) - '@radix-ui/react-progress@1.1.7(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021))(react@19.0.0-rc-45804af1-20241021)': - dependencies: - '@radix-ui/react-context': 1.1.2(@types/react@18.3.18)(react@19.0.0-rc-45804af1-20241021) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021))(react@19.0.0-rc-45804af1-20241021) - react: 19.0.0-rc-45804af1-20241021 - react-dom: 19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021) - optionalDependencies: - '@types/react': 18.3.18 - '@types/react-dom': 18.3.5(@types/react@18.3.18) - '@radix-ui/react-roving-focus@1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021))(react@19.0.0-rc-45804af1-20241021)': dependencies: '@radix-ui/primitive': 1.1.1 @@ -9738,7 +9712,7 @@ snapshots: dependencies: is-number: 7.0.0 - tokenlens@1.1.2: {} + tokenlens@1.0.0: {} trim-lines@3.0.1: {}