diff --git a/app/(chat)/api/chat/route.ts b/app/(chat)/api/chat/route.ts index 7cd24d5..9b0a396 100644 --- a/app/(chat)/api/chat/route.ts +++ b/app/(chat)/api/chat/route.ts @@ -6,7 +6,7 @@ import { streamText, } from 'ai'; import { auth, type UserType } from '@/app/(auth)/auth'; -import { systemPrompt } from '@/lib/ai/prompts'; +import { type RequestHints, systemPrompt } from '@/lib/ai/prompts'; import { deleteChatById, getChatById, @@ -25,6 +25,7 @@ import { isProductionEnvironment } from '@/lib/constants'; import { myProvider } from '@/lib/ai/providers'; import { entitlementsByUserType } from '@/lib/ai/entitlements'; import { postRequestBodySchema, type PostRequestBody } from './schema'; +import { geolocation } from '@vercel/functions'; export const maxDuration = 60; @@ -85,6 +86,15 @@ export async function POST(request: Request) { message, }); + const { longitude, latitude, city, country } = geolocation(request); + + const requestHints: RequestHints = { + longitude, + latitude, + city, + country, + }; + await saveMessages({ messages: [ { @@ -102,7 +112,7 @@ export async function POST(request: Request) { execute: (dataStream) => { const result = streamText({ model: myProvider.languageModel(selectedChatModel), - system: systemPrompt({ selectedChatModel }), + system: systemPrompt({ selectedChatModel, requestHints }), messages, maxSteps: 5, experimental_activeTools: diff --git a/lib/ai/prompts.ts b/lib/ai/prompts.ts index 7c4b0a8..c208c8b 100644 --- a/lib/ai/prompts.ts +++ b/lib/ai/prompts.ts @@ -1,4 +1,5 @@ -import { ArtifactKind } from '@/components/artifact'; +import type { ArtifactKind } from '@/components/artifact'; +import type { Geo } from '@vercel/functions'; export const artifactsPrompt = ` Artifacts is a special user interface mode that helps users with writing, editing, and other content creation tasks. When artifact is open, it is on the right side of the screen, while the conversation is on the left side. When creating or updating documents, changes are reflected in real-time on the artifacts and visible to the user. @@ -34,15 +35,34 @@ Do not update document right after creating it. Wait for user feedback or reques export const regularPrompt = 'You are a friendly assistant! Keep your responses concise and helpful.'; +export interface RequestHints { + latitude: Geo['latitude']; + longitude: Geo['longitude']; + city: Geo['city']; + country: Geo['country']; +} + +export const getRequestPromptFromHints = (requestHints: RequestHints) => `\ +About the origin of user's request: +- lat: ${requestHints.latitude} +- lon: ${requestHints.longitude} +- city: ${requestHints.city} +- country: ${requestHints.country} +`; + export const systemPrompt = ({ selectedChatModel, + requestHints, }: { selectedChatModel: string; + requestHints: RequestHints; }) => { + const requestPrompt = getRequestPromptFromHints(requestHints); + if (selectedChatModel === 'chat-model-reasoning') { - return regularPrompt; + return `${regularPrompt}\n\n${requestPrompt}`; } else { - return `${regularPrompt}\n\n${artifactsPrompt}`; + return `${regularPrompt}\n\n${requestPrompt}\n\n${artifactsPrompt}`; } }; diff --git a/package.json b/package.json index f28fa2c..fec1c6e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ai-chatbot", - "version": "3.0.10", + "version": "3.0.11", "private": true, "scripts": { "dev": "next dev --turbo", @@ -38,6 +38,7 @@ "@radix-ui/react-visually-hidden": "^1.1.0", "@vercel/analytics": "^1.3.1", "@vercel/blob": "^0.24.1", + "@vercel/functions": "^2.0.0", "@vercel/postgres": "^0.10.0", "ai": "4.3.4", "bcrypt-ts": "^5.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 97657c4..7e34ff7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,6 +65,9 @@ importers: '@vercel/blob': specifier: ^0.24.1 version: 0.24.1 + '@vercel/functions': + specifier: ^2.0.0 + version: 2.0.0 '@vercel/postgres': specifier: ^0.10.0 version: 0.10.0 @@ -1629,6 +1632,15 @@ packages: resolution: {integrity: sha512-wHzgKzvAuF4tRDoXk3wGBYzQZ9z2fLr4oftiR1hOclPEdA1aj2/0mizvO2l5w91eZlTAaFth0S1DlqrrXqpntg==} engines: {node: '>=16.14'} + '@vercel/functions@2.0.0': + resolution: {integrity: sha512-BSwIihLHoV18gerKZJyGuqd3rtaYM6rJvET1kOwKktshucyaHXTJel7Cxegs+sdX0NZqsX4LO2MFnMU2jG01Cw==} + engines: {node: '>= 18'} + peerDependencies: + '@aws-sdk/credential-provider-web-identity': '*' + peerDependenciesMeta: + '@aws-sdk/credential-provider-web-identity': + optional: true + '@vercel/postgres@0.10.0': resolution: {integrity: sha512-fSD23DxGND40IzSkXjcFcxr53t3Tiym59Is0jSYIFpG4/0f0KO9SGtcp1sXiebvPaGe7N/tU05cH4yt2S6/IPg==} engines: {node: '>=18.14'} @@ -4981,6 +4993,8 @@ snapshots: is-buffer: 2.0.5 undici: 5.28.5 + '@vercel/functions@2.0.0': {} + '@vercel/postgres@0.10.0': dependencies: '@neondatabase/serverless': 0.9.5 @@ -5618,7 +5632,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.7)(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.7(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -5640,7 +5654,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.7)(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.7(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3