vn6295337's picture
Fix: Track actual data source (SEC vs Yahoo) for fundamentals metrics
33d2228
import { AnalysisResponse } from './types'
// In production (HF Spaces), API is served from same origin - use empty string
// In development, use localhost:8000 (8002 is used by financials cluster)
const API_BASE_URL = import.meta.env.VITE_API_URL ?? (import.meta.env.PROD ? '' : 'http://localhost:8000')
// Stock search types
export interface StockResult {
symbol: string
name: string
exchange: string
match_type: string
}
export interface StockSearchResponse {
query: string
results: StockResult[]
}
// Activity log entry
export interface ActivityLogEntry {
timestamp: string
step: string
message: string
}
// Granular metric entry with optional temporal data
export interface MetricEntry {
timestamp: string
source: string // "volatility", "valuation", "fundamentals", etc.
metric: string // "beta", "P/E", "revenue", etc.
value: string | number
// Temporal fields (from SEC EDGAR data)
end_date?: string // Fiscal period end date, e.g., "2023-09-30"
fiscal_year?: number // Fiscal year number, e.g., 2023
form?: string // SEC form type: "10-K" (annual) or "10-Q" (quarterly)
data_source?: string // Actual data source: "sec_edgar" or "yahoo_finance"
}
// MCP status for each server (partial = some data but with errors)
export interface MCPStatus {
fundamentals: 'idle' | 'executing' | 'completed' | 'partial' | 'failed'
valuation: 'idle' | 'executing' | 'completed' | 'partial' | 'failed'
volatility: 'idle' | 'executing' | 'completed' | 'partial' | 'failed'
macro: 'idle' | 'executing' | 'completed' | 'partial' | 'failed'
news: 'idle' | 'executing' | 'completed' | 'partial' | 'failed'
sentiment: 'idle' | 'executing' | 'completed' | 'partial' | 'failed'
}
// LLM provider status
export interface LLMStatus {
groq: 'idle' | 'executing' | 'completed' | 'failed'
gemini: 'idle' | 'executing' | 'completed' | 'failed'
openrouter: 'idle' | 'executing' | 'completed' | 'failed'
}
// Workflow status with activity log and MCP status
export interface WorkflowStatus {
status: 'starting' | 'running' | 'completed' | 'error' | 'aborted'
current_step: 'input' | 'cache' | 'researcher' | 'analyzer' | 'critic' | 'output' | 'completed'
revision_count: number
score: number
activity_log: ActivityLogEntry[]
metrics: MetricEntry[]
mcp_status: MCPStatus
llm_status: LLMStatus
provider_used?: string
data_source?: string
error?: string // Error message for error/aborted states
}
export interface WorkflowStartResponse {
workflow_id: string
}
// Search stocks by query
export async function searchStocks(query: string): Promise<StockSearchResponse> {
const response = await fetch(`${API_BASE_URL}/api/stocks/search?q=${encodeURIComponent(query)}`)
if (!response.ok) {
throw new Error('Failed to search stocks')
}
return response.json()
}
// User API keys for LLM providers
export interface UserApiKeys {
groq?: string
gemini?: string
openrouter?: string
}
// Start analysis with ticker support
export async function startAnalysis(
companyName: string,
ticker: string = '',
strategyFocus: string = 'Competitive Position',
skipCache: boolean = false,
userApiKeys: UserApiKeys = {}
): Promise<WorkflowStartResponse> {
const response = await fetch(`${API_BASE_URL}/analyze`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: companyName,
ticker: ticker,
strategy_focus: strategyFocus,
skip_cache: skipCache,
user_api_keys: userApiKeys
}),
})
if (!response.ok) {
throw new Error('Failed to start analysis')
}
return response.json()
}
export async function getWorkflowStatus(workflowId: string): Promise<WorkflowStatus> {
const response = await fetch(`${API_BASE_URL}/workflow/${workflowId}/status`)
if (!response.ok) {
throw new Error('Failed to get workflow status')
}
return response.json()
}
export async function getWorkflowResult(workflowId: string): Promise<AnalysisResponse> {
const response = await fetch(`${API_BASE_URL}/workflow/${workflowId}/result`)
if (!response.ok) {
throw new Error('Failed to get workflow result')
}
return response.json()
}
export async function checkHealth(): Promise<{ status: string; active_workflows?: number }> {
const response = await fetch(`${API_BASE_URL}/health`)
if (!response.ok) {
throw new Error('API health check failed')
}
return response.json()
}