chore: bump package versions + fix linter

This commit is contained in:
Vasily Zubarev
2025-07-23 10:34:49 +02:00
parent dee915ffd6
commit 8897134901
6 changed files with 98 additions and 95 deletions

View File

@@ -1,9 +1,9 @@
"use server"
import { ActionState } from "@/lib/actions"
import { AnalyzeAttachment } from "./attachments"
import { updateFile } from "@/models/files"
import { getSettings, getLLMSettings } from "@/models/settings"
import { getLLMSettings, getSettings } from "@/models/settings"
import { AnalyzeAttachment } from "./attachments"
import { requestLLM } from "./providers/llmProvider"
export type AnalysisResult = {
@@ -18,7 +18,6 @@ export async function analyzeTransaction(
fileId: string,
userId: string
): Promise<ActionState<AnalysisResult>> {
const settings = await getSettings(userId)
const llmSettings = getLLMSettings(settings)
@@ -45,7 +44,7 @@ export async function analyzeTransaction(
success: true,
data: {
output: result,
tokensUsed: tokensUsed
tokensUsed: tokensUsed,
},
}
} catch (error) {

View File

@@ -30,79 +30,76 @@ export interface LLMResponse {
async function requestLLMUnified(config: LLMConfig, req: LLMRequest): Promise<LLMResponse> {
try {
const temperature = 0;
let model: any;
const temperature = 0
let model: any
if (config.provider === "openai") {
model = new ChatOpenAI({
apiKey: config.apiKey,
model: config.model,
temperature: temperature,
});
})
} else if (config.provider === "google") {
model = new ChatGoogleGenerativeAI({
apiKey: config.apiKey,
model: config.model,
temperature: temperature,
});
})
} else if (config.provider === "mistral") {
model = new ChatMistralAI({
apiKey: config.apiKey,
model: config.model,
temperature: temperature,
});
})
} else {
return {
output: {},
provider: config.provider,
error: "Unknown provider",
};
}
}
const structuredModel = model.withStructuredOutput(req.schema, { 'name': 'transaction'});
const structuredModel = model.withStructuredOutput(req.schema, { name: "transaction" })
let message_content: any = [{ type: "text", text: req.prompt }];
let message_content: any = [{ type: "text", text: req.prompt }]
if (req.attachments && req.attachments.length > 0) {
const images = req.attachments.map(att => ({
const images = req.attachments.map((att) => ({
type: "image_url",
image_url: {
url: `data:${att.contentType};base64,${att.base64}`
url: `data:${att.contentType};base64,${att.base64}`,
},
}));
message_content.push(...images);
}))
message_content.push(...images)
}
const messages: BaseMessage[] = [
new HumanMessage({ content: message_content })
];
const messages: BaseMessage[] = [new HumanMessage({ content: message_content })]
const response = await structuredModel.invoke(messages);
const response = await structuredModel.invoke(messages)
return {
output: response,
provider: config.provider,
};
}
} catch (error: any) {
return {
output: {},
provider: config.provider,
error: error instanceof Error ? error.message : `${config.provider} request failed`,
};
}
}
}
export async function requestLLM(settings: LLMSettings, req: LLMRequest): Promise<LLMResponse> {
for (const config of settings.providers) {
if (!config.apiKey || !config.model) {
console.info('Skipping provider:', config.provider);
continue;
console.info("Skipping provider:", config.provider)
continue
}
console.info('Use provider:', config.provider);
console.info("Use provider:", config.provider)
const response = await requestLLMUnified(config, req);
const response = await requestLLMUnified(config, req)
if (!response.error) {
return response;
}
else {
return response
} else {
console.error(response.error)
}
}
@@ -111,5 +108,5 @@ export async function requestLLM(settings: LLMSettings, req: LLMRequest): Promis
output: {},
provider: settings.providers[0]?.provider || "openai",
error: "All LLM providers failed or are not configured",
};
}
}

View File

@@ -16,7 +16,8 @@ export const fieldsToJsonSchema = (fields: Field[]) => {
...schemaProperties,
items: {
type: "array",
description: "Separate items, products or transactions in the file which have own name and price or sum. Find all items!",
description:
"Separate items, products or transactions in the file which have own name and price or sum. Find all items!",
items: {
type: "object",
properties: schemaProperties,

View File

@@ -7,19 +7,22 @@ import { fieldsToJsonSchema } from "@/ai/schema"
import { transactionFormSchema } from "@/forms/transactions"
import { ActionState } from "@/lib/actions"
import { getCurrentUser, isAiBalanceExhausted, isSubscriptionExpired } from "@/lib/auth"
import config from "@/lib/config"
import { getTransactionFileUploadPath, getUserUploadsDirectory, safePathJoin, unsortedFilePath } from "@/lib/files"
import {
getDirectorySize,
getTransactionFileUploadPath,
getUserUploadsDirectory,
safePathJoin,
unsortedFilePath,
} from "@/lib/files"
import { DEFAULT_PROMPT_ANALYSE_NEW_FILE } from "@/models/defaults"
import { createFile, deleteFile, getFileById, updateFile } from "@/models/files"
import { createTransaction, updateTransactionFiles, TransactionData } from "@/models/transactions"
import { createTransaction, TransactionData, updateTransactionFiles } from "@/models/transactions"
import { updateUser } from "@/models/users"
import { Category, Field, File, Project, Transaction } from "@/prisma/client"
import { mkdir, rename } from "fs/promises"
import { randomUUID } from "crypto"
import { mkdir, readFile, rename, writeFile } from "fs/promises"
import { revalidatePath } from "next/cache"
import path from "path"
import { randomUUID } from "crypto"
import { readFile, writeFile } from "fs/promises"
import { getDirectorySize } from "@/lib/files"
export async function analyzeFileAction(
file: File,

View File

@@ -1,11 +1,11 @@
import { Card, CardDescription, CardTitle } from "@/components/ui/card"
import { ColoredText } from "@/components/ui/colored-text"
import config from "@/lib/config"
import { PROVIDERS } from "@/lib/llm-providers"
import { getSelfHostedUser } from "@/models/users"
import { ShieldAlert } from "lucide-react"
import Image from "next/image"
import { redirect } from "next/navigation"
import { PROVIDERS } from "@/lib/llm-providers"
import SelfHostedSetupFormClient from "./setup-form-client"
export default async function SelfHostedWelcomePage() {
@@ -32,7 +32,6 @@ export default async function SelfHostedWelcomePage() {
redirect(config.selfHosted.redirectUrl)
}
// Собираем дефолтные ключи для всех провайдеров
const defaultProvider = PROVIDERS[0].key
const defaultApiKeys: Record<string, string> = {
openai: config.ai.openaiApiKey ?? "",

100
package-lock.json generated
View File

@@ -941,9 +941,9 @@
}
},
"node_modules/@eslint/config-array": {
"version": "0.19.2",
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz",
"integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==",
"version": "0.21.0",
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz",
"integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -956,9 +956,9 @@
}
},
"node_modules/@eslint/config-helpers": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.1.0.tgz",
"integrity": "sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA==",
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz",
"integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -966,9 +966,9 @@
}
},
"node_modules/@eslint/core": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz",
"integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==",
"version": "0.15.1",
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz",
"integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -979,9 +979,9 @@
}
},
"node_modules/@eslint/eslintrc": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz",
"integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==",
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
"integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1003,13 +1003,16 @@
}
},
"node_modules/@eslint/js": {
"version": "9.22.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.22.0.tgz",
"integrity": "sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==",
"version": "9.31.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.31.0.tgz",
"integrity": "sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://eslint.org/donate"
}
},
"node_modules/@eslint/object-schema": {
@@ -1023,13 +1026,13 @@
}
},
"node_modules/@eslint/plugin-kit": {
"version": "0.2.7",
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz",
"integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==",
"version": "0.3.4",
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.4.tgz",
"integrity": "sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@eslint/core": "^0.12.0",
"@eslint/core": "^0.15.1",
"levn": "^0.4.1"
},
"engines": {
@@ -5558,9 +5561,9 @@
"license": "MIT"
},
"node_modules/acorn": {
"version": "8.14.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
"version": "8.15.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@@ -7101,20 +7104,20 @@
}
},
"node_modules/eslint": {
"version": "9.22.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.22.0.tgz",
"integrity": "sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ==",
"version": "9.31.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.31.0.tgz",
"integrity": "sha512-QldCVh/ztyKJJZLr4jXNUByx3gR+TDYZCRXEktiZoUR3PGy4qCmSbkxcIle8GEwGpb5JBZazlaJ/CxLidXdEbQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.12.1",
"@eslint/config-array": "^0.19.2",
"@eslint/config-helpers": "^0.1.0",
"@eslint/core": "^0.12.0",
"@eslint/eslintrc": "^3.3.0",
"@eslint/js": "9.22.0",
"@eslint/plugin-kit": "^0.2.7",
"@eslint/config-array": "^0.21.0",
"@eslint/config-helpers": "^0.3.0",
"@eslint/core": "^0.15.0",
"@eslint/eslintrc": "^3.3.1",
"@eslint/js": "9.31.0",
"@eslint/plugin-kit": "^0.3.1",
"@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1",
"@humanwhocodes/retry": "^0.4.2",
@@ -7125,9 +7128,9 @@
"cross-spawn": "^7.0.6",
"debug": "^4.3.2",
"escape-string-regexp": "^4.0.0",
"eslint-scope": "^8.3.0",
"eslint-visitor-keys": "^4.2.0",
"espree": "^10.3.0",
"eslint-scope": "^8.4.0",
"eslint-visitor-keys": "^4.2.1",
"espree": "^10.4.0",
"esquery": "^1.5.0",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
@@ -7433,9 +7436,9 @@
}
},
"node_modules/eslint-scope": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz",
"integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==",
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
"integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -7450,9 +7453,9 @@
}
},
"node_modules/eslint-visitor-keys": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
"integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -7463,15 +7466,15 @@
}
},
"node_modules/espree": {
"version": "10.3.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz",
"integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==",
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
"integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"acorn": "^8.14.0",
"acorn": "^8.15.0",
"acorn-jsx": "^5.3.2",
"eslint-visitor-keys": "^4.2.0"
"eslint-visitor-keys": "^4.2.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -7744,9 +7747,9 @@
}
},
"node_modules/form-data": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz",
"integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
"license": "MIT",
"optional": true,
"peer": true,
@@ -7754,6 +7757,7 @@
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.12"
},
"engines": {