Add DeepSeek V4 scan review
This commit is contained in:
@@ -77,6 +77,7 @@ const pendingCityMarketScanRequests = new Map<
|
||||
>();
|
||||
const pendingAssistantRequests = new Map<string, Promise<AssistantChatResponse>>();
|
||||
const pendingScanTerminalRequests = new Map<string, Promise<ScanTerminalResponse>>();
|
||||
const pendingScanTerminalAiRequests = new Map<string, Promise<ScanTerminalResponse>>();
|
||||
const PRIORITY_WARM_SESSION_KEY = "polyWeather_priority_warm_v1";
|
||||
|
||||
type CityCacheMeta = {
|
||||
@@ -438,6 +439,44 @@ export const dashboardClient = {
|
||||
return request;
|
||||
},
|
||||
|
||||
async reviewScanTerminalWithAi(payload: {
|
||||
filters: ScanTerminalFilters;
|
||||
snapshotId?: string | null;
|
||||
}) {
|
||||
const snapshotId = String(payload.snapshotId || "").trim();
|
||||
const requestKey = [
|
||||
snapshotId || "latest",
|
||||
JSON.stringify(payload.filters || {}),
|
||||
].join("::");
|
||||
const existing = pendingScanTerminalAiRequests.get(requestKey);
|
||||
if (existing) {
|
||||
return existing;
|
||||
}
|
||||
const request = fetch("/api/scan/terminal/ai", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
cache: "no-store",
|
||||
body: JSON.stringify({
|
||||
filters: payload.filters,
|
||||
snapshot_id: snapshotId || null,
|
||||
}),
|
||||
})
|
||||
.then(async (response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}`);
|
||||
}
|
||||
return response.json() as Promise<ScanTerminalResponse>;
|
||||
})
|
||||
.finally(() => {
|
||||
pendingScanTerminalAiRequests.delete(requestKey);
|
||||
});
|
||||
pendingScanTerminalAiRequests.set(requestKey, request);
|
||||
return request;
|
||||
},
|
||||
|
||||
async getHistory(cityName: string, options?: { includeRecords?: boolean }) {
|
||||
const includeRecords = options?.includeRecords === true;
|
||||
const requestKey = `${normalizeCityName(cityName)}::${
|
||||
|
||||
@@ -535,10 +535,29 @@ export interface ScanOpportunityRow {
|
||||
signal_status?: string | null;
|
||||
candidate_count?: number | null;
|
||||
resolved_market_type?: string | null;
|
||||
ai_decision?: "approve" | "veto" | "downgrade" | "neutral" | string | null;
|
||||
ai_rank?: number | null;
|
||||
ai_confidence?: string | null;
|
||||
ai_reason_zh?: string | null;
|
||||
ai_reason_en?: string | null;
|
||||
ai_model_cluster_note?: string | null;
|
||||
}
|
||||
|
||||
export interface PrimarySignal extends ScanOpportunityRow {}
|
||||
|
||||
export interface ScanAiReview {
|
||||
status?: "ready" | "disabled" | "missing_key" | "failed" | "no_rows" | "no_snapshot" | "snapshot_mismatch" | string;
|
||||
model?: string | null;
|
||||
cached?: boolean;
|
||||
generated_at?: string | null;
|
||||
reason?: string | null;
|
||||
summary_zh?: string | null;
|
||||
summary_en?: string | null;
|
||||
recommended_count?: number | null;
|
||||
vetoed_count?: number | null;
|
||||
downgraded_count?: number | null;
|
||||
}
|
||||
|
||||
export interface ScanTerminalResponse {
|
||||
generated_at: string;
|
||||
snapshot_id?: string | null;
|
||||
@@ -563,6 +582,7 @@ export interface ScanTerminalResponse {
|
||||
};
|
||||
top_signal?: PrimarySignal | null;
|
||||
rows: ScanOpportunityRow[];
|
||||
ai_scan?: ScanAiReview | null;
|
||||
}
|
||||
|
||||
export interface IntradayMeteorologySignal {
|
||||
|
||||
Reference in New Issue
Block a user