[update] added validation for article data in NewsList.vue
, removed unused Cypress config, expanded LLM models in example.env
, adjusted context size and max article length in backend configuration, and updated workspace naming in yarn.lock
This commit is contained in:
@@ -8,11 +8,11 @@ MIN_CRON_HOURS = float(os.getenv("MIN_CRON_HOURS", 0.5))
|
|||||||
DEFAULT_CRON_HOURS = float(os.getenv("CRON_HOURS", MIN_CRON_HOURS))
|
DEFAULT_CRON_HOURS = float(os.getenv("CRON_HOURS", MIN_CRON_HOURS))
|
||||||
CRON_HOURS = max(MIN_CRON_HOURS, DEFAULT_CRON_HOURS)
|
CRON_HOURS = max(MIN_CRON_HOURS, DEFAULT_CRON_HOURS)
|
||||||
SYNC_COOLDOWN_MINUTES = int(os.getenv("SYNC_COOLDOWN_MINUTES", 30))
|
SYNC_COOLDOWN_MINUTES = int(os.getenv("SYNC_COOLDOWN_MINUTES", 30))
|
||||||
LLM_MODEL = os.getenv("LLM_MODEL", "mistral-nemo:12b")
|
LLM_MODEL = os.getenv("LLM_MODEL", "phi3:3.8b-mini-128k-instruct-q4_0")
|
||||||
LLM_TIMEOUT_SECONDS = int(os.getenv("LLM_TIMEOUT_SECONDS", 180))
|
LLM_TIMEOUT_SECONDS = int(os.getenv("LLM_TIMEOUT_SECONDS", 180))
|
||||||
OLLAMA_API_TIMEOUT_SECONDS = int(os.getenv("OLLAMA_API_TIMEOUT_SECONDS", 10))
|
OLLAMA_API_TIMEOUT_SECONDS = int(os.getenv("OLLAMA_API_TIMEOUT_SECONDS", 10))
|
||||||
ARTICLE_FETCH_TIMEOUT = int(os.getenv("ARTICLE_FETCH_TIMEOUT", 30))
|
ARTICLE_FETCH_TIMEOUT = int(os.getenv("ARTICLE_FETCH_TIMEOUT", 30))
|
||||||
MAX_ARTICLE_LENGTH = int(os.getenv("MAX_ARTICLE_LENGTH", 10_000))
|
MAX_ARTICLE_LENGTH = int(os.getenv("MAX_ARTICLE_LENGTH", 40_000))
|
||||||
|
|
||||||
frontend_path = os.path.join(
|
frontend_path = os.path.join(
|
||||||
os.path.dirname(os.path.dirname(os.path.dirname(__file__))),
|
os.path.dirname(os.path.dirname(os.path.dirname(__file__))),
|
||||||
|
@@ -209,7 +209,7 @@ class NewsFetcher:
|
|||||||
"format": "json",
|
"format": "json",
|
||||||
"options": {
|
"options": {
|
||||||
"num_gpu": 1, # Force GPU usage
|
"num_gpu": 1, # Force GPU usage
|
||||||
"num_ctx": 128_000, # Context size
|
"num_ctx": 64_000, # Context size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -11,10 +11,11 @@ MIN_CRON_HOURS=0.5
|
|||||||
SYNC_COOLDOWN_MINUTES=30
|
SYNC_COOLDOWN_MINUTES=30
|
||||||
|
|
||||||
# LLM model to use for summarization
|
# LLM model to use for summarization
|
||||||
LLM_MODEL=qwen2:7b-instruct-q4_K_M
|
LLM_MODEL=qwen2:7b-instruct-q4_K_M # ca 7-9GB (typisch 8GB)
|
||||||
LLM_MODEL=phi3:3.8b-mini-128k-instruct-q4_0
|
LLM_MODEL=phi3:3.8b-mini-128k-instruct-q4_0 # ca 6-8GB (langer kontext)
|
||||||
LLM_MODEL=mistral-nemo:12b
|
LLM_MODEL=mistral-nemo:12b # ca 16-24+GB
|
||||||
LLM_MODEL=cnjack/mistral-samll-3.1:24b-it-q4_K_S
|
LLM_MODEL=cnjack/mistral-samll-3.1:24b-it-q4_K_S # ca 22GB
|
||||||
|
LLM_MODEL=yarn-mistral:7b-64k-q4_K_M # ca 11GB
|
||||||
|
|
||||||
# Timeout in seconds for LLM requests
|
# Timeout in seconds for LLM requests
|
||||||
LLM_TIMEOUT_SECONDS=180
|
LLM_TIMEOUT_SECONDS=180
|
||||||
|
Binary file not shown.
@@ -1,8 +0,0 @@
|
|||||||
import { defineConfig } from 'cypress'
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
e2e: {
|
|
||||||
specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
|
|
||||||
baseUrl: 'http://localhost:4173',
|
|
||||||
},
|
|
||||||
})
|
|
@@ -14,9 +14,10 @@
|
|||||||
|
|
||||||
<!-- Articles Grid -->
|
<!-- Articles Grid -->
|
||||||
<div v-else class="grid gap-4 sm:gap-6 md:grid-cols-2 xl:grid-cols-3">
|
<div v-else class="grid gap-4 sm:gap-6 md:grid-cols-2 xl:grid-cols-3">
|
||||||
|
<template v-for="article in news.articles"
|
||||||
|
:key="article.id">
|
||||||
<article
|
<article
|
||||||
v-for="article in news.articles"
|
v-if="isValidArticleContent(article)"
|
||||||
:key="article.id"
|
|
||||||
class="flex flex-col h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 hover:shadow-md dark:hover:shadow-lg dark:hover:shadow-gray-800/50 transition-all duration-200 overflow-hidden group"
|
class="flex flex-col h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 hover:shadow-md dark:hover:shadow-lg dark:hover:shadow-gray-800/50 transition-all duration-200 overflow-hidden group"
|
||||||
>
|
>
|
||||||
<!-- Article Header -->
|
<!-- Article Header -->
|
||||||
@@ -28,7 +29,7 @@
|
|||||||
</span>
|
</span>
|
||||||
<time
|
<time
|
||||||
:datetime="new Date(article.published * 1000).toISOString()"
|
:datetime="new Date(article.published * 1000).toISOString()"
|
||||||
:title="new Date(article.published * 1000).toLocaleString(userLocale.value, {
|
:title="new Date(article.published * 1000).toLocaleString(userLocale, {
|
||||||
dateStyle: 'full',
|
dateStyle: 'full',
|
||||||
timeStyle: 'long'
|
timeStyle: 'long'
|
||||||
})"
|
})"
|
||||||
@@ -83,6 +84,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Loading State & Load More Trigger -->
|
<!-- Loading State & Load More Trigger -->
|
||||||
@@ -129,6 +131,37 @@ const loadMoreArticles = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface Article {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
summary: string;
|
||||||
|
url: string;
|
||||||
|
published: number;
|
||||||
|
country: string;
|
||||||
|
created_at: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const INVALID_MARKERS = ['---', '...', '…', 'Title', 'Summary', 'Titel', 'Zusammenfassung'] as const;
|
||||||
|
const REQUIRED_TEXT_FIELDS = ['title', 'summary', 'url'] as const;
|
||||||
|
|
||||||
|
const isValidArticleContent = (article: Article): boolean => {
|
||||||
|
const hasEmptyRequiredFields = REQUIRED_TEXT_FIELDS.some(
|
||||||
|
field => article[field as keyof Pick<Article, typeof REQUIRED_TEXT_FIELDS[number]>].length === 0
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hasEmptyRequiredFields) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasInvalidMarkers = REQUIRED_TEXT_FIELDS.some(field =>
|
||||||
|
INVALID_MARKERS.some(marker =>
|
||||||
|
article[field as keyof Pick<Article, typeof REQUIRED_TEXT_FIELDS[number]>].includes(marker)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return !hasInvalidMarkers;
|
||||||
|
};
|
||||||
|
|
||||||
const observer = ref<IntersectionObserver | null>(null);
|
const observer = ref<IntersectionObserver | null>(null);
|
||||||
const loadMoreTrigger = ref<HTMLElement | null>(null);
|
const loadMoreTrigger = ref<HTMLElement | null>(null);
|
||||||
|
|
||||||
|
@@ -6470,9 +6470,9 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"owly-news-summariser@workspace:.":
|
"owly-news@workspace:.":
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "owly-news-summariser@workspace:."
|
resolution: "owly-news@workspace:."
|
||||||
dependencies:
|
dependencies:
|
||||||
"@tailwindcss/vite": "npm:^4.1.11"
|
"@tailwindcss/vite": "npm:^4.1.11"
|
||||||
"@tsconfig/node22": "npm:^22.0.2"
|
"@tsconfig/node22": "npm:^22.0.2"
|
||||||
|
Reference in New Issue
Block a user