Save local changes (GSC/Bing integrations) before merging PR #354

This commit is contained in:
ajaysi
2026-02-13 13:11:27 +05:30
parent 43e66835ac
commit 08a1f4a1d8
144 changed files with 8310 additions and 2748 deletions

View File

@@ -545,7 +545,7 @@ class TaskWorkflowOrchestrator {
private loadPersistedWorkflows(): void {
if (this.config.persistProgress) {
try {
const keys = Object.keys(localStorage).filter(key => key.startsWith('workflow-'));
const keys = Object.keys(localStorage).filter(key => key.startsWith('workflow-') && key !== 'workflow-store');
keys.forEach(key => {
const workflowData = localStorage.getItem(key);
if (workflowData) {
@@ -554,7 +554,8 @@ class TaskWorkflowOrchestrator {
// Ensure workflow has required properties
if (!workflow.id || !workflow.date || !workflow.userId) {
console.warn(`Invalid workflow data for key ${key}, skipping`);
console.warn(`Invalid workflow data for key ${key}, skipping and cleaning up`);
localStorage.removeItem(key);
return;
}

View File

@@ -35,7 +35,7 @@ const BILLING_BASE_URL = API_BASE_URL
// Create axios instance with default config
const billingAPI = axios.create({
baseURL: BILLING_BASE_URL,
timeout: 10000,
timeout: 60000, // Increased to 60s to prevent timeouts in dev/slow networks
headers: {
'Content-Type': 'application/json',
},
@@ -202,6 +202,7 @@ function coerceUsageStats(raw: any): UsageStats {
const geminiData = providerBreakdown.gemini;
const mistralData = providerBreakdown.mistral; // Backend sends 'mistral' for HuggingFace
const huggingfaceData = providerBreakdown.huggingface;
const wavespeedData = providerBreakdown.wavespeed;
// Create properly typed ProviderUsage objects
const geminiUsage: ProviderUsage = geminiData && typeof geminiData === 'object' && 'calls' in geminiData
@@ -214,11 +215,16 @@ function coerceUsageStats(raw: any): UsageStats {
: (mistralData && typeof mistralData === 'object' && 'calls' in mistralData)
? { calls: Number(mistralData.calls) || 0, tokens: Number(mistralData.tokens) || 0, cost: Number(mistralData.cost) || 0 }
: { calls: 0, tokens: 0, cost: 0 };
const wavespeedUsage: ProviderUsage = wavespeedData && typeof wavespeedData === 'object' && 'calls' in wavespeedData
? { calls: Number(wavespeedData.calls) || 0, tokens: Number(wavespeedData.tokens) || 0, cost: Number(wavespeedData.cost) || 0 }
: { calls: 0, tokens: 0, cost: 0 };
// Create ProviderBreakdown with only gemini and huggingface
const providerBreakdownCoerced: ProviderBreakdown = {
gemini: geminiUsage,
huggingface: huggingfaceUsage,
wavespeed: wavespeedUsage,
};
// Extract usage percentages - only include gemini and huggingface
@@ -234,7 +240,7 @@ function coerceUsageStats(raw: any): UsageStats {
// Calculate total_cost from provider breakdown
// Always calculate from provider breakdown to ensure accuracy, but prefer backend total if it's more accurate
const backendTotalCost = typeof raw?.total_cost === 'number' ? raw.total_cost : 0;
const calculatedTotalCost = geminiUsage.cost + huggingfaceUsage.cost;
const calculatedTotalCost = geminiUsage.cost + huggingfaceUsage.cost + wavespeedUsage.cost;
// Use the maximum of backend cost and calculated cost to ensure we show the actual cost
// If backend cost is 0 but we have provider costs, use calculated cost
@@ -249,18 +255,20 @@ function coerceUsageStats(raw: any): UsageStats {
finalTotalCost: totalCost,
geminiCost: geminiUsage.cost,
huggingfaceCost: huggingfaceUsage.cost,
wavespeedCost: wavespeedUsage.cost,
geminiCalls: geminiUsage.calls,
huggingfaceCalls: huggingfaceUsage.calls,
wavespeedCalls: wavespeedUsage.calls,
});
}
// Calculate total_calls and total_tokens from provider breakdown if needed
const backendTotalCalls = typeof raw?.total_calls === 'number' ? raw.total_calls : 0;
const calculatedTotalCalls = geminiUsage.calls + huggingfaceUsage.calls;
const calculatedTotalCalls = geminiUsage.calls + huggingfaceUsage.calls + wavespeedUsage.calls;
const totalCalls = backendTotalCalls > 0 ? backendTotalCalls : calculatedTotalCalls;
const backendTotalTokens = typeof raw?.total_tokens === 'number' ? raw.total_tokens : 0;
const calculatedTotalTokens = geminiUsage.tokens + huggingfaceUsage.tokens;
const calculatedTotalTokens = geminiUsage.tokens + huggingfaceUsage.tokens + wavespeedUsage.tokens;
const totalTokens = backendTotalTokens > 0 ? backendTotalTokens : calculatedTotalTokens;
const coerced: UsageStats = {

View File

@@ -233,7 +233,7 @@ export interface BlogPublishResponse {
post_id?: string;
}
export interface TaskStatusResponse {
export interface TaskStatusResponse<T = BlogResearchResponse> {
task_id: string;
status: 'pending' | 'running' | 'completed' | 'failed';
created_at: string;
@@ -241,7 +241,7 @@ export interface TaskStatusResponse {
timestamp: string;
message: string;
}>;
result?: BlogResearchResponse;
result?: T;
error?: string;
// Subscription error details (set by backend when subscription limit is exceeded)
error_status?: number; // HTTP status code (429 for usage limit, 402 for subscription expired)

View File

@@ -26,7 +26,7 @@ const MONITORING_BASE_URL = API_BASE_URL
// Use shorter timeout for health checks to prevent blocking dashboard
const monitoringAPI = axios.create({
baseURL: MONITORING_BASE_URL,
timeout: 5000, // Reduced from 10000 to 5000ms for faster failure
timeout: 30000, // Increased from 5000 to 30000ms to prevent false positives in dev
headers: {
'Content-Type': 'application/json',
},