Add three-stage cross-domain news research and reading briefings
Group original news into tagged fact packages, review each package with evidence and read-only research, and build complete 72-hour reading lists with independent model selections. Add paused RSS/Atom subscriptions, news-scoped Skills, versioned analysis records, and locked deployment support for SearXNG. Preserve original news and keep live migration and legacy AI cleanup separately authorized. Validate with 604 backend tests, 49 frontend tests, 19 CI control tests, lint, type checks, production build, and disposable PostgreSQL migration and three-stage smoke checks.
This commit is contained in:
1 parent
ae35d3d608
commit
80d266dba7
44 files changed
+2682
-574
No files matched your search
@@ -43,3 +43,5 @@ export function subscribeCrawlerApi(signal: AbortSignal, version: number, onOpen
|
||||
if (name === "log") onMessage(data)
|
||||
})
|
||||
}
|
||||
|
||||
export const createRssApi = (data: Crawler.RssInput) => request<{ code: string }>({ url: "/crawler/sources/rss", method: "post", data })
|
||||
@@ -62,6 +62,7 @@ export interface CrawlLog {
|
||||
}
|
||||
|
||||
export interface SourcePatch {
|
||||
name?: string
|
||||
enabled?: boolean
|
||||
interval_seconds?: number
|
||||
/** ISO 时间表示回补到该时间;null 表示取消回补 */
|
||||
@@ -73,3 +74,5 @@ export type PatchSourceResponseData = null
|
||||
export type ListLogsResponseData = CrawlLog[]
|
||||
|
||||
export type RestartCrawlerResponseData = null
|
||||
|
||||
export interface RssInput { name: string, url: string, interval_seconds: number }
|
||||
@@ -5,7 +5,10 @@ export const getRiskSettingsApi = () => request<Risk.Settings>({ url: "/risk/set
|
||||
export const saveRiskSettingsApi = (data: Risk.Settings) => request<null>({ url: "/risk/settings", method: "put", data })
|
||||
export const enableRiskApi = (data: Risk.Settings) => request<null>({ url: "/risk/enable", method: "post", timeout: 650000, data })
|
||||
export const getRiskOverviewApi = (hours: number) => request<Risk.Overview>({ url: "/risk/overview", method: "get", params: { hours } })
|
||||
export const listRiskEventsApi = (params: Risk.EventQuery) => request<{ items: Risk.RiskEvent[], total: number }>({ url: "/risk/events", method: "get", params })
|
||||
export const getRiskEventApi = (id: number) => request<{ event: Risk.RiskEvent, history: Risk.Analysis[] }>({ url: `/risk/events/${id}`, method: "get" })
|
||||
export const listRiskAnalysesApi = (params: { news_id?: number, revision_no?: number, failed?: boolean }, notify = true) => request<Risk.Analysis[]>({ url: "/risk/analyses", method: "get", params, notify })
|
||||
export const retryRiskAnalysisApi = (id: number) => request<null>({ url: `/risk/analyses/${id}/retry`, method: "post" })
|
||||
export const listRiskEventsApi = (params: Risk.EventQuery) => request<{ items: Risk.RiskEvent[], total: number }>({ url: "/risk/summaries", method: "get", params })
|
||||
export const getRiskEventApi = (id: number) => request<{ evidence: { id: number, kind: string, data: unknown, fetched_at: string }[], event: Risk.RiskEvent, history: Risk.Analysis[], versions: { id: number, revision: number, state: string, model: string, result: Risk.RiskResult | null, error: string | null, analyzed_at: string | null }[] }>({ url: `/risk/summaries/${id}`, method: "get" })
|
||||
export const listRiskAnalysesApi = (params: { news_id?: number, revision_no?: number, failed?: boolean, stage?: string }, notify = true) => request<Risk.Analysis[]>({ url: "/risk/tasks", method: "get", params, notify })
|
||||
export const retryRiskAnalysisApi = (id: number, stage = "grouping") => request<null>({ url: `/risk/tasks/${id}/retry`, method: "post", params: { stage } })
|
||||
|
||||
export const listNewsSummariesApi = (newsId: number, revision: number) => request<Risk.RiskEvent[]>({ url: `/risk/news/${newsId}/summaries`, method: "get", params: { revision_no: revision } })
|
||||
export const createNewsSkillTemplatesApi = () => request<{ grouping_skill_id: number, analysis_skill_id: number, outlook_skill_id: number }>({ url: "/risk/skill-templates", method: "post" })
|
||||
@@ -2,24 +2,55 @@ export interface RiskResult {
|
||||
summary: string
|
||||
reasoning: string
|
||||
uncertainty: string
|
||||
evidence: string
|
||||
evidence?: string
|
||||
direction: string
|
||||
verification: string
|
||||
confidence: string
|
||||
stars: number
|
||||
risk_stars: number
|
||||
importance_stars: number
|
||||
facts?: string
|
||||
timeline?: string
|
||||
asset_impacts?: string
|
||||
opinions?: string
|
||||
counter_evidence?: string
|
||||
watchpoints?: string
|
||||
claims?: { statement: string, verdict: string, evidence_refs: { article_id: number, quote: string }[] }[]
|
||||
related_packages?: { id: number, relation: string, reason: string }[]
|
||||
evidence_refs?: { article_id: number, quote: string }[]
|
||||
}
|
||||
export interface RiskEvent {
|
||||
tags: string[]
|
||||
content_kind: string
|
||||
importance_stars: number
|
||||
article_count: number
|
||||
id: number
|
||||
title: string
|
||||
category: string
|
||||
entities: string[]
|
||||
stars: number
|
||||
risk_stars: number
|
||||
peak_stars: number
|
||||
result: RiskResult
|
||||
result: RiskResult | null
|
||||
state: string
|
||||
analyzed_at: string | null
|
||||
revision: number
|
||||
published_revision: number
|
||||
error: string | null
|
||||
published_at: string
|
||||
updated_at: string
|
||||
}
|
||||
export interface Settings { enabled: boolean, provider_id: number | null, model: string, start_at: string }
|
||||
export interface Settings {
|
||||
enabled: boolean
|
||||
provider_id: number | null
|
||||
model: string
|
||||
second_provider_id: number | null
|
||||
second_model: string
|
||||
third_provider_id: number | null
|
||||
third_model: string
|
||||
grouping_skill_id: number | null
|
||||
analysis_skill_id: number | null
|
||||
outlook_skill_id: number | null
|
||||
start_at: string | null
|
||||
}
|
||||
export interface Analysis {
|
||||
id: number
|
||||
news_id: number
|
||||
@@ -31,10 +62,22 @@ export interface Analysis {
|
||||
analyzed_at: string | null
|
||||
historical: boolean
|
||||
}
|
||||
export interface Reading { id: number, revision: number, priority: number, reason: string }
|
||||
export interface Trend { summary: string, conditions: string, counter_evidence: string, watchpoints: string }
|
||||
export interface Briefing {
|
||||
reading: Reading[]
|
||||
expansion: Reading[]
|
||||
as_of: string
|
||||
synthesis: { summary: string, market: string, short_term: Trend, medium_term: Trend } | null
|
||||
inputs: { id: number, revision: number, category: string, tags: string[], result: RiskResult & { title: string } }[]
|
||||
}
|
||||
export interface Overview {
|
||||
briefing: Briefing | null
|
||||
stage2: Record<string, number>
|
||||
stage3?: { state: string, pending: boolean, heartbeat: string | null }
|
||||
as_of: string
|
||||
counts: Record<string, number>
|
||||
coverage: { total: number, done: number, failed: number, pending: number, processing: number }
|
||||
coverage: { total: number, done: number, skipped: number, failed: number, pending: number, processing: number }
|
||||
scenario: { direction: string, summary: string, conditions: string, counter_factors: string, uncertainty: string, event_ids: number[] } | null
|
||||
snapshot_at: string | null
|
||||
quotes: { at: string, BTCUSDT?: { lastPrice: string, priceChangePercent: string }, ETHUSDT?: { lastPrice: string, priceChangePercent: string } } | null
|
||||
@@ -42,4 +85,4 @@ export interface Overview {
|
||||
error: string | null
|
||||
heartbeat: string | null
|
||||
}
|
||||
export interface EventQuery { hours?: number, stars?: number, q?: string, start?: string, end?: string, page?: number }
|
||||
export interface EventQuery { tag?: string, importance?: number, hours?: number, stars?: number, q?: string, category?: string, asset?: string, start?: string, end?: string, page?: number }
|
||||
@@ -3,6 +3,7 @@ export type NodeKind = "folder" | "skill"
|
||||
export interface SkillNode {
|
||||
id: number
|
||||
parent_id: number | null
|
||||
scope: "shared" | "news"
|
||||
kind: NodeKind
|
||||
name: string
|
||||
path: string
|
||||
@@ -28,7 +29,7 @@ export type ListSkillTreeResponseData = SkillNode[]
|
||||
|
||||
export type CreateSkillNodeResponseData = SkillNode
|
||||
|
||||
export interface CreateSkillNodeBodyRequestData { parent_id: number | null, kind: NodeKind, name: string, priority?: number, content?: string }
|
||||
export interface CreateSkillNodeBodyRequestData { parent_id: number | null, kind: NodeKind, name: string, priority?: number, scope?: "shared" | "news", content?: string }
|
||||
|
||||
export type PatchSkillNodeResponseData = SkillNode
|
||||
|
||||
|
||||
Reference in new issue
Block a user