cite-agent 1.2.13__py3-none-any.whl → 1.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of cite-agent might be problematic. Click here for more details.

cite_agent/__version__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "1.2.13"
1
+ __version__ = "1.3.1"
@@ -2594,23 +2594,125 @@ class EnhancedNocturnalAgent:
2594
2594
  if workflow_response:
2595
2595
  return workflow_response
2596
2596
 
2597
- # Analyze request to determine what APIs to call
2598
- request_analysis = await self._analyze_request_type(request.question)
2599
-
2600
- # Debug: Check what was detected
2597
+ # Initialize
2598
+ api_results = {}
2599
+ tools_used = []
2601
2600
  debug_mode = os.getenv("NOCTURNAL_DEBUG", "").lower() == "1"
2601
+
2602
+ # ========================================================================
2603
+ # PRIORITY 1: SHELL PLANNING (Reasoning Layer - Runs FIRST for ALL modes)
2604
+ # ========================================================================
2605
+ # This determines USER INTENT before fetching any data
2606
+ # Prevents waste: "find cm522" won't trigger Archive API, "look into it" won't web search
2607
+ # Works in BOTH production and dev modes
2608
+
2609
+ shell_action = "none" # Will be: pwd|ls|find|none
2610
+
2611
+ # Quick check if query might need shell
2612
+ question_lower = request.question.lower()
2613
+ might_need_shell = any(word in question_lower for word in [
2614
+ 'directory', 'folder', 'where', 'find', 'list', 'files', 'look', 'search', 'check', 'into'
2615
+ ])
2616
+
2617
+ if might_need_shell and self.shell_session:
2618
+ # Ask LLM planner: What shell command should we run?
2619
+ planner_prompt = f"""You are a shell command planner. Determine what shell command to run.
2620
+
2621
+ User query: "{request.question}"
2622
+ Previous conversation: {json.dumps(self.conversation_history[-2:]) if self.conversation_history else "None"}
2623
+
2624
+ Respond ONLY with JSON:
2625
+ {{
2626
+ "action": "pwd|ls|find|none",
2627
+ "search_target": "cm522" (if find),
2628
+ "search_path": "~/Downloads" (if find),
2629
+ "target_path": "/full/path" (if ls on previous result)
2630
+ }}
2631
+
2632
+ Examples:
2633
+ "where am i?" → {{"action": "pwd"}}
2634
+ "what files here?" → {{"action": "ls"}}
2635
+ "find cm522 in downloads" → {{"action": "find", "search_target": "cm522", "search_path": "~/Downloads"}}
2636
+ "look into it" + Previous: "Found /path/to/dir" → {{"action": "ls", "target_path": "/path/to/dir"}}
2637
+ "Tesla revenue" → {{"action": "none"}}
2638
+
2639
+ JSON:"""
2640
+
2641
+ try:
2642
+ plan_response = await self.call_backend_query(
2643
+ query=planner_prompt,
2644
+ conversation_history=[],
2645
+ api_results={},
2646
+ tools_used=[]
2647
+ )
2648
+
2649
+ plan_text = plan_response.response.strip()
2650
+ if '```' in plan_text:
2651
+ plan_text = plan_text.split('```')[1].replace('json', '').strip()
2652
+
2653
+ plan = json.loads(plan_text)
2654
+ shell_action = plan.get("action", "none")
2655
+
2656
+ if debug_mode:
2657
+ print(f"🔍 SHELL PLAN: {plan}")
2658
+
2659
+ # Execute shell command based on plan
2660
+ if shell_action == "pwd":
2661
+ pwd_output = self.execute_command("pwd")
2662
+ api_results["shell_info"] = {"current_directory": pwd_output.strip()}
2663
+ tools_used.append("shell_execution")
2664
+
2665
+ elif shell_action == "ls":
2666
+ target = plan.get("target_path")
2667
+ if target:
2668
+ ls_output = self.execute_command(f"ls -lah {target}")
2669
+ api_results["shell_info"] = {
2670
+ "directory_contents": ls_output,
2671
+ "target_path": target
2672
+ }
2673
+ else:
2674
+ ls_output = self.execute_command("ls -lah")
2675
+ api_results["shell_info"] = {"directory_contents": ls_output}
2676
+ tools_used.append("shell_execution")
2677
+
2678
+ elif shell_action == "find":
2679
+ search_target = plan.get("search_target", "")
2680
+ search_path = plan.get("search_path", "~")
2681
+ if search_target:
2682
+ find_cmd = f"find {search_path} -maxdepth 4 -type d -iname '*{search_target}*' 2>/dev/null | head -20"
2683
+ find_output = self.execute_command(find_cmd)
2684
+ if debug_mode:
2685
+ print(f"🔍 FIND: {find_cmd}")
2686
+ print(f"🔍 OUTPUT: {repr(find_output)}")
2687
+ if find_output.strip():
2688
+ api_results["shell_info"] = {
2689
+ "search_results": f"Searched for '*{search_target}*' in {search_path}:\n{find_output}"
2690
+ }
2691
+ else:
2692
+ api_results["shell_info"] = {
2693
+ "search_results": f"No directories matching '{search_target}' found in {search_path}"
2694
+ }
2695
+ tools_used.append("shell_execution")
2696
+
2697
+ except Exception as e:
2698
+ if debug_mode:
2699
+ print(f"🔍 Shell planner failed: {e}, continuing without shell")
2700
+ shell_action = "none"
2701
+
2702
+ # ========================================================================
2703
+ # PRIORITY 2: DATA APIs (Only if shell didn't fully handle the query)
2704
+ # ========================================================================
2705
+ # If shell_action = pwd/ls/find, we might still want data APIs
2706
+ # But we skip vague queries to save tokens
2707
+
2708
+ # Analyze what data APIs are needed (only if not pure shell command)
2709
+ request_analysis = await self._analyze_request_type(request.question)
2602
2710
  if debug_mode:
2603
2711
  print(f"🔍 Request analysis: {request_analysis}")
2604
2712
 
2605
- # Check if query is too vague - skip EXPENSIVE API calls to save tokens
2606
- # But still allow web search (cheap and flexible)
2607
2713
  is_vague = self._is_query_too_vague_for_apis(request.question)
2608
2714
  if debug_mode and is_vague:
2609
- print(f"🔍 Query detected as VAGUE - skipping Archive/FinSight, but may use web search")
2610
-
2611
- # Call appropriate APIs (Archive, FinSight) - BOTH production and dev mode
2612
- api_results = {}
2613
- tools_used = []
2715
+ print(f"🔍 Query is VAGUE - skipping expensive APIs")
2614
2716
 
2615
2717
  # Skip Archive/FinSight if query is too vague, but still allow web search later
2616
2718
  if not is_vague:
@@ -2629,232 +2731,141 @@ class EnhancedNocturnalAgent:
2629
2731
  api_results["research"] = result
2630
2732
  tools_used.append("archive_api")
2631
2733
 
2632
- # FinSight API for financial data
2734
+ # FinSight API for financial data - Use LLM for ticker/metric extraction
2633
2735
  if "finsight" in request_analysis.get("apis", []):
2634
- tickers = self._extract_tickers_from_text(request.question)
2635
- if not tickers:
2636
- # Try common company name mappings
2637
- question_lower = request.question.lower()
2638
- if "apple" in question_lower:
2639
- tickers = ["AAPL"]
2640
- elif "tesla" in question_lower:
2641
- tickers = ["TSLA"]
2642
- elif "microsoft" in question_lower:
2643
- tickers = ["MSFT"]
2644
- elif "google" in question_lower or "alphabet" in question_lower:
2645
- tickers = ["GOOGL"]
2646
-
2647
- if debug_mode:
2648
- print(f"🔍 Extracted tickers: {tickers}")
2649
-
2650
- if tickers:
2651
- # Detect what metric user is asking for
2652
- question_lower = request.question.lower()
2653
- metric = "revenue" # Default
2736
+ # LLM extracts ticker + metric (more accurate than regex)
2737
+ finance_prompt = f"""Extract financial query details from user's question.
2738
+
2739
+ User query: "{request.question}"
2740
+
2741
+ Respond with JSON:
2742
+ {{
2743
+ "tickers": ["AAPL", "TSLA"] (stock symbols - infer from company names if needed),
2744
+ "metric": "revenue|marketCap|price|netIncome|eps|freeCashFlow|grossProfit"
2745
+ }}
2746
+
2747
+ Examples:
2748
+ - "Tesla revenue" → {{"tickers": ["TSLA"], "metric": "revenue"}}
2749
+ - "What's Apple worth?" → {{"tickers": ["AAPL"], "metric": "marketCap"}}
2750
+ - "tsla stock price" → {{"tickers": ["TSLA"], "metric": "price"}}
2751
+ - "Microsoft profit" → {{"tickers": ["MSFT"], "metric": "netIncome"}}
2752
+
2753
+ JSON:"""
2754
+
2755
+ try:
2756
+ finance_response = await self.call_backend_query(
2757
+ query=finance_prompt,
2758
+ conversation_history=[],
2759
+ api_results={},
2760
+ tools_used=[]
2761
+ )
2762
+
2763
+ import json as json_module
2764
+ finance_text = finance_response.response.strip()
2765
+ if '```' in finance_text:
2766
+ finance_text = finance_text.split('```')[1].replace('json', '').strip()
2654
2767
 
2655
- if any(word in question_lower for word in ['market cap', 'marketcap', 'market value', 'valuation']):
2656
- metric = "marketCap"
2657
- elif any(word in question_lower for word in ['stock price', 'share price', 'current price', 'trading at']):
2658
- metric = "price"
2659
- elif 'profit' in question_lower and 'gross' not in question_lower:
2660
- metric = "netIncome"
2661
- elif 'earnings' in question_lower or 'eps' in question_lower:
2662
- metric = "eps"
2663
- elif any(word in question_lower for word in ['cash flow', 'cashflow']):
2664
- metric = "freeCashFlow"
2768
+ finance_plan = json_module.loads(finance_text)
2769
+ tickers = finance_plan.get("tickers", [])
2770
+ metric = finance_plan.get("metric", "revenue")
2665
2771
 
2666
- # Call FinSight with detected metric
2667
2772
  if debug_mode:
2668
- print(f"🔍 Calling FinSight API: calc/{tickers[0]}/{metric}")
2669
- financial_data = await self._call_finsight_api(f"calc/{tickers[0]}/{metric}")
2773
+ print(f"🔍 LLM FINANCE PLAN: tickers={tickers}, metric={metric}")
2774
+
2775
+ if tickers:
2776
+ # Call FinSight with extracted ticker + metric
2777
+ financial_data = await self._call_finsight_api(f"calc/{tickers[0]}/{metric}")
2778
+ if debug_mode:
2779
+ print(f"🔍 FinSight returned: {list(financial_data.keys()) if financial_data else None}")
2780
+ if financial_data and "error" not in financial_data:
2781
+ api_results["financial"] = financial_data
2782
+ tools_used.append("finsight_api")
2783
+
2784
+ except Exception as e:
2670
2785
  if debug_mode:
2671
- print(f"🔍 FinSight returned: {list(financial_data.keys()) if financial_data else None}")
2672
- if financial_data and "error" not in financial_data:
2673
- api_results["financial"] = financial_data
2674
- tools_used.append("finsight_api")
2675
- else:
2676
- if debug_mode and financial_data:
2677
- print(f"🔍 FinSight error: {financial_data.get('error')}")
2786
+ print(f"🔍 Finance LLM extraction failed: {e}")
2678
2787
 
2679
- # Web Search fallback - ALWAYS available even for vague queries
2680
- # Use for: market share, industry data, current events, prices, anything not in APIs
2681
- if self.web_search:
2682
- question_lower = request.question.lower()
2683
- # Only search if query needs data and APIs didn't provide it
2684
- needs_web_search = (
2685
- ('market share' in question_lower) or
2686
- ('market size' in question_lower) or
2687
- ('industry' in question_lower and not api_results.get('research')) or
2688
- ('price' in question_lower and ('today' in question_lower or 'current' in question_lower or 'now' in question_lower)) or
2689
- ('bitcoin' in question_lower or 'btc' in question_lower or 'crypto' in question_lower) or
2690
- ('exchange rate' in question_lower or 'forex' in question_lower) or
2691
- (not api_results and 'latest' in question_lower) # Latest news/data
2692
- )
2693
-
2694
- if needs_web_search or (not api_results and len(request.question.split()) > 5):
2695
- try:
2696
- if debug_mode:
2697
- print(f"🔍 Using web search for: {request.question[:50]}...")
2788
+ # ========================================================================
2789
+ # PRIORITY 3: WEB SEARCH (Fallback - only if shell didn't handle AND no data yet)
2790
+ # ========================================================================
2791
+ # Only web search if:
2792
+ # - Shell said "none" (not a directory/file operation)
2793
+ # - We don't have enough data from Archive/FinSight
2794
+
2795
+ if self.web_search and shell_action == "none":
2796
+ # Ask LLM: Should we web search for this?
2797
+ web_decision_prompt = f"""Should we use web search for this query?
2798
+
2799
+ User query: "{request.question}"
2800
+ Data already available: {list(api_results.keys())}
2801
+ Shell action: {shell_action}
2802
+
2803
+ Respond with JSON:
2804
+ {{
2805
+ "use_web_search": true/false,
2806
+ "reason": "why or why not"
2807
+ }}
2808
+
2809
+ Use web search for:
2810
+ - Market share/size (not in SEC filings)
2811
+ - Current prices (Bitcoin, commodities, real-time data)
2812
+ - Industry data, statistics
2813
+ - Recent events, news
2814
+ - Questions not answered by existing data
2815
+
2816
+ Don't use if:
2817
+ - Shell already handled it (pwd/ls/find)
2818
+ - Question answered by research/financial APIs
2819
+ - Pure opinion question
2820
+
2821
+ JSON:"""
2822
+
2823
+ try:
2824
+ web_decision_response = await self.call_backend_query(
2825
+ query=web_decision_prompt,
2826
+ conversation_history=[],
2827
+ api_results={},
2828
+ tools_used=[]
2829
+ )
2830
+
2831
+ import json as json_module
2832
+ decision_text = web_decision_response.response.strip()
2833
+ if '```' in decision_text:
2834
+ decision_text = decision_text.split('```')[1].replace('json', '').strip()
2835
+
2836
+ decision = json_module.loads(decision_text)
2837
+ needs_web_search = decision.get("use_web_search", False)
2838
+
2839
+ if debug_mode:
2840
+ print(f"🔍 WEB SEARCH DECISION: {needs_web_search}, reason: {decision.get('reason')}")
2841
+
2842
+ if needs_web_search:
2698
2843
  web_results = await self.web_search.search_web(request.question, num_results=3)
2699
2844
  if web_results and "results" in web_results:
2700
2845
  api_results["web_search"] = web_results
2701
2846
  tools_used.append("web_search")
2702
2847
  if debug_mode:
2703
2848
  print(f"🔍 Web search returned: {len(web_results.get('results', []))} results")
2704
- except Exception as e:
2705
- if debug_mode:
2706
- print(f"🔍 Web search failed: {e}")
2849
+
2850
+ except Exception as e:
2851
+ if debug_mode:
2852
+ print(f"🔍 Web search decision failed: {e}")
2707
2853
 
2708
- # PRODUCTION MODE: Check for shell/code execution needs FIRST
2854
+ # PRODUCTION MODE: Call backend LLM with all gathered data
2709
2855
  if self.client is None:
2710
- # Check if query needs directory/file info or exploration
2711
- question_lower = request.question.lower()
2712
-
2713
- # Basic info queries
2714
- needs_shell_info = any(phrase in question_lower for phrase in [
2715
- 'directory', 'folder', 'where am i', 'pwd', 'current location',
2716
- 'list files', 'what files', 'ls', 'files in', 'show files',
2717
- 'data files', 'csv files', 'check if file', 'file exists'
2718
- ])
2719
-
2720
- # Fuzzy search queries (find similar directories/files)
2721
- needs_find = any(phrase in question_lower for phrase in [
2722
- 'looking for', 'find', 'search for', 'similar to',
2723
- 'go to', 'cd to', 'navigate to', 'or something', 'forgot the name',
2724
- 'look into', 'check what', 'what\'s in'
2725
- ])
2726
-
2727
- if (needs_shell_info or needs_find) and self.shell_session:
2728
- # Execute exploration commands
2729
- try:
2730
- api_results["shell_info"] = {}
2731
-
2732
- # Always include current location
2733
- pwd_output = self.execute_command("pwd")
2734
- api_results["shell_info"]["current_directory"] = pwd_output.strip()
2735
-
2736
- if needs_shell_info and not needs_find:
2737
- # Just list current directory
2738
- ls_output = self.execute_command("ls -lah")
2739
- api_results["shell_info"]["directory_contents"] = ls_output
2740
-
2741
- if needs_find:
2742
- # Smart search: extract directory name and location hints
2743
- import re
2744
-
2745
- # Check if user is referring to previous context ("it", "there")
2746
- has_pronoun = any(word in question_lower for word in ['it', 'there', 'that folder', 'that directory'])
2747
- pronoun_resolved = False
2748
-
2749
- if has_pronoun and len(self.conversation_history) > 0:
2750
- # Look for directory path in last assistant message
2751
- last_assistant = None
2752
- for msg in reversed(self.conversation_history):
2753
- if msg.get('role') == 'assistant':
2754
- last_assistant = msg.get('content', '')
2755
- break
2756
-
2757
- if last_assistant:
2758
- # Extract paths like /home/user/Downloads/cm522-main
2759
- paths = re.findall(r'(/[\w/.-]+)', last_assistant)
2760
- if paths:
2761
- # List contents of the first path found
2762
- target_path = paths[0]
2763
- ls_output = self.execute_command(f"ls -lah {target_path}")
2764
- api_results["shell_info"]["directory_contents"] = ls_output
2765
- api_results["shell_info"]["target_path"] = target_path
2766
- tools_used.append("shell_execution")
2767
- pronoun_resolved = True
2768
-
2769
- # Generic search if no pronoun or pronoun not resolved
2770
- if not pronoun_resolved:
2771
- # SMART EXTRACTION: Use pattern matching + common sense
2772
- import re
2773
-
2774
- # Strategy: Look for quoted strings or alphanumeric codes
2775
- # Priority 1: Quoted strings ("cm522", 'my_folder')
2776
- quoted = re.findall(r'["\']([^"\']+)["\']', request.question)
2777
-
2778
- if quoted:
2779
- search_terms = quoted
2780
- else:
2781
- # Priority 2: Alphanumeric codes/IDs (cm522, hw03, proj_2024)
2782
- # Pattern: letters + numbers mixed, or underscores/dashes
2783
- codes = re.findall(r'\b([a-zA-Z]*\d+[a-zA-Z0-9_-]*|[a-zA-Z0-9]*[_-]+[a-zA-Z0-9]+)\b', request.question)
2784
-
2785
- # Priority 3: Capitalize words (likely proper nouns: GitHub, MyProject)
2786
- capitalized = re.findall(r'\b([A-Z][a-zA-Z0-9_-]+)\b', request.question)
2787
-
2788
- # Priority 4: Long words (≥ 6 chars, likely meaningful)
2789
- long_words = re.findall(r'\b([a-zA-Z]{6,})\b', request.question)
2790
-
2791
- # Combine and dedupe
2792
- search_terms = list(dict.fromkeys(codes + capitalized + long_words))
2793
-
2794
- # Filter out common words
2795
- common = {
2796
- 'looking', 'folder', 'directory', 'called', 'something',
2797
- 'downloads', 'documents', 'computer', 'somewhere'
2798
- }
2799
- search_terms = [t for t in search_terms if t.lower() not in common][:2]
2800
-
2801
- debug_mode = os.getenv("NOCTURNAL_DEBUG", "").lower() == "1"
2802
- if debug_mode:
2803
- print(f"🔍 EXTRACTED SEARCH TERMS: {search_terms}")
2804
-
2805
- if not search_terms:
2806
- search_terms = [''] # Empty search to show "no target found"
2807
-
2808
- # Detect location hints
2809
- search_path = "~" # Default to home
2810
- if 'downloads' in question_lower:
2811
- search_path = "~/Downloads"
2812
- elif 'documents' in question_lower:
2813
- search_path = "~/Documents"
2814
-
2815
- search_results = []
2816
-
2817
- for name in search_terms:
2818
- if not name:
2819
- continue
2820
-
2821
- # Search with increasing depth
2822
- find_cmd = f"find {search_path} -maxdepth 4 -type d -iname '*{name}*' 2>/dev/null | head -20"
2823
- find_output = self.execute_command(find_cmd)
2824
-
2825
- debug_mode = os.getenv("NOCTURNAL_DEBUG", "").lower() == "1"
2826
- if debug_mode:
2827
- print(f"🔍 FIND EXECUTED: {find_cmd}")
2828
- print(f"🔍 FIND OUTPUT: {repr(find_output)}")
2829
-
2830
- if find_output.strip():
2831
- search_results.append(f"Searched for '*{name}*' in {search_path}:\n{find_output}")
2832
-
2833
- if search_results:
2834
- api_results["shell_info"]["search_results"] = "\n\n".join(search_results)
2835
- else:
2836
- api_results["shell_info"]["search_results"] = f"No directories found matching query in {search_path}"
2837
-
2838
- tools_used.append("shell_execution")
2839
- except Exception as e:
2840
- if debug_mode:
2841
- print(f"🔍 Shell execution failed: {e}")
2842
-
2843
- # DEBUG: Log exactly what we're sending to backend
2844
- debug_mode = os.getenv("NOCTURNAL_DEBUG", "").lower() == "1"
2845
- if debug_mode and api_results.get("shell_info", {}).get("search_results"):
2846
- print(f"🔍 SENDING TO BACKEND:")
2847
- print(f"🔍 shell_info.search_results = {repr(api_results['shell_info']['search_results'])}")
2856
+ # DEBUG: Log what we're sending
2857
+ if debug_mode and api_results.get("shell_info"):
2858
+ print(f"🔍 SENDING TO BACKEND: shell_info keys = {list(api_results.get('shell_info', {}).keys())}")
2848
2859
 
2849
2860
  # Call backend and UPDATE CONVERSATION HISTORY
2850
2861
  response = await self.call_backend_query(
2851
2862
  query=request.question,
2852
2863
  conversation_history=self.conversation_history[-10:],
2853
- api_results=api_results, # Include the data!
2854
- tools_used=tools_used # Pass tools list for history
2864
+ api_results=api_results,
2865
+ tools_used=tools_used
2855
2866
  )
2856
2867
 
2857
- # CRITICAL: Save to conversation history for context
2868
+ # CRITICAL: Save to conversation history
2858
2869
  self.conversation_history.append({"role": "user", "content": request.question})
2859
2870
  self.conversation_history.append({"role": "assistant", "content": response.response})
2860
2871
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cite-agent
3
- Version: 1.2.13
3
+ Version: 1.3.1
4
4
  Summary: Terminal AI assistant for academic research with citation verification
5
5
  Home-page: https://github.com/Spectating101/cite-agent
6
6
  Author: Cite-Agent Team
@@ -1,6 +1,6 @@
1
1
  cite_agent/__init__.py,sha256=wAXV2v8nNOmIAd0rh8196ItBl9hHWBVOBl5Re4VB77I,1645
2
2
  cite_agent/__main__.py,sha256=6x3lltwG-iZHeQbN12rwvdkPDfd2Rmdk71tOOaC89Mw,179
3
- cite_agent/__version__.py,sha256=rQSlPcfj4yT4krIq6epTVQyBzIX4etVOgfupVkM-RnU,23
3
+ cite_agent/__version__.py,sha256=-ypEJktJToAL9by62JJKWEzDo_KPCQtmE5kwFgX24z4,22
4
4
  cite_agent/account_client.py,sha256=yLuzhIJoIZuXHXGbaVMzDxRATQwcy-wiaLnUrDuwUhI,5725
5
5
  cite_agent/agent_backend_only.py,sha256=H4DH4hmKhT0T3rQLAb2xnnJVjxl3pOZaljL9r6JndFY,6314
6
6
  cite_agent/ascii_plotting.py,sha256=lk8BaECs6fmjtp4iH12G09-frlRehAN7HLhHt2crers,8570
@@ -11,7 +11,7 @@ cite_agent/cli_conversational.py,sha256=RAmgRNRyB8gQ8QLvWU-Tt23j2lmA34rQNT5F3_7S
11
11
  cite_agent/cli_enhanced.py,sha256=EAaSw9qtiYRWUXF6_05T19GCXlz9cCSz6n41ASnXIPc,7407
12
12
  cite_agent/cli_workflow.py,sha256=4oS_jW9D8ylovXbEFdsyLQONt4o0xxR4Xatfcc4tnBs,11641
13
13
  cite_agent/dashboard.py,sha256=VGV5XQU1PnqvTsxfKMcue3j2ri_nvm9Be6O5aVays_w,10502
14
- cite_agent/enhanced_ai_agent.py,sha256=i7q4gWB3KsQSfOhNBZMJw9GRcK-_GQc4O56exumROiE,167565
14
+ cite_agent/enhanced_ai_agent.py,sha256=R6fFT_h_o8DJe9hOosvXececvNR7v7iDmF37mo3EwlA,164710
15
15
  cite_agent/rate_limiter.py,sha256=-0fXx8Tl4zVB4O28n9ojU2weRo-FBF1cJo9Z5jC2LxQ,10908
16
16
  cite_agent/session_manager.py,sha256=B0MXSOsXdhO3DlvTG7S8x6pmGlYEDvIZ-o8TZM23niQ,9444
17
17
  cite_agent/setup_config.py,sha256=3m2e3gw0srEWA0OygdRo64r-8HK5ohyXfct0c__CF3s,16817
@@ -22,7 +22,7 @@ cite_agent/updater.py,sha256=udoAAN4gBKAvKDV7JTh2FJO_jIhNk9bby4x6n188MEY,8458
22
22
  cite_agent/web_search.py,sha256=FZCuNO7MAITiOIbpPbJyt2bzbXPzQla-9amJpnMpW_4,6520
23
23
  cite_agent/workflow.py,sha256=a0YC0Mzz4or1C5t2gZcuJBQ0uMOZrooaI8eLu2kkI0k,15086
24
24
  cite_agent/workflow_integration.py,sha256=A9ua0DN5pRtuU0cAwrUTGvqt2SXKhEHQbrHx16EGnDM,10910
25
- cite_agent-1.2.13.dist-info/licenses/LICENSE,sha256=XJkyO4IymhSUniN1ENY6lLrL2729gn_rbRlFK6_Hi9M,1074
25
+ cite_agent-1.3.1.dist-info/licenses/LICENSE,sha256=XJkyO4IymhSUniN1ENY6lLrL2729gn_rbRlFK6_Hi9M,1074
26
26
  src/__init__.py,sha256=0eEpjRfjRjOTilP66y-AbGNslBsVYr_clE-bZUzsX7s,40
27
27
  src/services/__init__.py,sha256=pTGLCH_84mz4nGtYMwQES5w-LzoSulUtx_uuNM6r-LA,4257
28
28
  src/services/simple_enhanced_main.py,sha256=IJoOplCqcVUg3GvN_BRyAhpGrLm_WEPy2jmHcNCY6R0,9257
@@ -49,8 +49,8 @@ src/services/research_service/synthesizer.py,sha256=lCcu37PWhWVNphHKaJJDIC-JQ5OI
49
49
  src/services/search_service/__init__.py,sha256=UZFXdd7r6wietQ2kESXEyGffdfBbpghquecQde7auF4,137
50
50
  src/services/search_service/indexer.py,sha256=u3-uwdAfmahWWsdebDF9i8XIyp7YtUMIHzlmBLBnPPM,7252
51
51
  src/services/search_service/search_engine.py,sha256=S9HqQ_mk-8W4d4MUOgBbEGQGV29-eSuceSFvVb4Xk-k,12500
52
- cite_agent-1.2.13.dist-info/METADATA,sha256=D3xbwKTOyFfuX2P0ZgpaQtrbTqS8mDi8Jga1T9DNpQQ,12232
53
- cite_agent-1.2.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
54
- cite_agent-1.2.13.dist-info/entry_points.txt,sha256=bJ0u28nFIxQKH1PWQ2ak4PV-FAjhoxTC7YADEdDenFw,83
55
- cite_agent-1.2.13.dist-info/top_level.txt,sha256=TgOFqJTIy8vDZuOoYA2QgagkqZtfhM5Acvt_IsWzAKo,15
56
- cite_agent-1.2.13.dist-info/RECORD,,
52
+ cite_agent-1.3.1.dist-info/METADATA,sha256=se84qa1NRyJR88LGSrVhbeuy4XvGJSkTsHF-sE0LOjo,12231
53
+ cite_agent-1.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
54
+ cite_agent-1.3.1.dist-info/entry_points.txt,sha256=bJ0u28nFIxQKH1PWQ2ak4PV-FAjhoxTC7YADEdDenFw,83
55
+ cite_agent-1.3.1.dist-info/top_level.txt,sha256=TgOFqJTIy8vDZuOoYA2QgagkqZtfhM5Acvt_IsWzAKo,15
56
+ cite_agent-1.3.1.dist-info/RECORD,,