vectara-agentic 0.4.6__py3-none-any.whl → 0.4.8__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 vectara-agentic might be problematic. Click here for more details.

vectara_agentic/tools.py CHANGED
@@ -6,7 +6,9 @@ import inspect
6
6
  import importlib
7
7
  import os
8
8
  import asyncio
9
+ import urllib.parse
9
10
  from typing import Callable, List, Dict, Any, Optional, Union
11
+ import logging
10
12
 
11
13
  from retrying import retry
12
14
  from pydantic import BaseModel, Field
@@ -64,6 +66,103 @@ LI_packages = {
64
66
  },
65
67
  }
66
68
 
69
+ def normalize_url(url):
70
+ """
71
+ Normalize URL for consistent comparison by handling percent-encoding.
72
+
73
+ Args:
74
+ url (str): The URL to normalize
75
+
76
+ Returns:
77
+ str: Normalized URL with consistent percent-encoding
78
+ """
79
+ if not url:
80
+ return url
81
+
82
+ try:
83
+ # Decode percent-encoded characters
84
+ decoded = urllib.parse.unquote(url)
85
+ # Re-encode consistently using standard safe characters
86
+ normalized = urllib.parse.quote(decoded, safe=':/?#[]@!$&\'()*+,;=')
87
+ return normalized
88
+ except Exception as e:
89
+ logging.warning(f"Error normalizing URL '{url}': {e}")
90
+ return url
91
+
92
+ def citation_appears_in_text(citation_text, citation_url, response_text):
93
+ """
94
+ Check if citation appears in response text using multiple matching strategies.
95
+ Handles citation formatting internally based on available text and URL.
96
+
97
+ Args:
98
+ citation_text (str): The text part of the citation (can be None)
99
+ citation_url (str): The URL part of the citation (can be None)
100
+ response_text (str): The response text to search in
101
+
102
+ Returns:
103
+ bool: True if citation appears in response text
104
+ """
105
+ if not response_text:
106
+ return False
107
+
108
+ # If no citation info available, return False
109
+ # Empty strings should be treated as None
110
+ if not citation_text and not citation_url:
111
+ return False
112
+
113
+ # Generate possible citation formats based on available data
114
+ citation_formats = []
115
+
116
+ # Normalize empty strings to None for cleaner logic
117
+ if citation_text == "":
118
+ citation_text = None
119
+ if citation_url == "":
120
+ citation_url = None
121
+
122
+ if citation_text and citation_url:
123
+ citation_formats.append(f"[{citation_text}]({citation_url})")
124
+ # Also try with normalized URL
125
+ normalized_url = normalize_url(citation_url)
126
+ if normalized_url != citation_url:
127
+ citation_formats.append(f"[{citation_text}]({normalized_url})")
128
+ # Also try with decoded URL (for cases where input is encoded but response has spaces)
129
+ decoded_url = urllib.parse.unquote(citation_url)
130
+ if decoded_url != citation_url:
131
+ citation_formats.append(f"[{citation_text}]({decoded_url})")
132
+ # Also try with aggressive encoding (encode more characters)
133
+ aggressive_encoded = urllib.parse.quote(decoded_url, safe=':/?#')
134
+ if aggressive_encoded not in (citation_url, normalized_url):
135
+ citation_formats.append(f"[{citation_text}]({aggressive_encoded})")
136
+ elif citation_url:
137
+ # Handle case where only URL is available (original logic: "[({url})]")
138
+ citation_formats.append(f"[({citation_url})]")
139
+ normalized_url = normalize_url(citation_url)
140
+ if normalized_url != citation_url:
141
+ citation_formats.append(f"[({normalized_url})]")
142
+ decoded_url = urllib.parse.unquote(citation_url)
143
+ if decoded_url != citation_url:
144
+ citation_formats.append(f"[({decoded_url})]")
145
+
146
+ # Strategy 1: Exact citation format matches
147
+ for citation_format in citation_formats:
148
+ if citation_format in response_text:
149
+ return True
150
+
151
+ # Strategy 2: URL appears anywhere in response (more lenient)
152
+ # Only apply this strategy if we have both citation_text and citation_url
153
+ # URL-only matching happens in Strategy 1 through citation formats
154
+ if citation_text and citation_url:
155
+ normalized_url = normalize_url(citation_url)
156
+ # Try both encoded and decoded versions
157
+ decoded_url = urllib.parse.unquote(citation_url)
158
+
159
+ if (citation_url in response_text or
160
+ normalized_url in response_text or
161
+ decoded_url in response_text):
162
+ return True
163
+
164
+ return False
165
+
67
166
 
68
167
  @retry(stop_max_attempt_number=3, wait_exponential_multiplier=1000, wait_exponential_max=10000)
69
168
  def _query_with_retry(vectara_query_engine, query):
@@ -595,11 +694,16 @@ class VectaraToolFactory:
595
694
  part_data = {k: v for k, v in node_metadata.items() if k != 'document'}
596
695
  template_data['part'] = to_obj(part_data)
597
696
 
598
- formatted_citation_text = computed_citations_text_pattern.format(**template_data)
599
- formatted_citation_url = computed_citations_url_pattern.format(**template_data)
600
- expected_citation = f"[{formatted_citation_text}]({formatted_citation_url})"
697
+ try:
698
+ formatted_citation_text = computed_citations_text_pattern.format(**template_data)
699
+ except Exception:
700
+ formatted_citation_text = None
701
+ try:
702
+ formatted_citation_url = computed_citations_url_pattern.format(**template_data)
703
+ except Exception:
704
+ formatted_citation_url = None
601
705
 
602
- if expected_citation in response_text:
706
+ if citation_appears_in_text(formatted_citation_text, formatted_citation_url, response_text):
603
707
  citation_metadata.append({
604
708
  'doc_id': node_id,
605
709
  'text': node_text,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vectara_agentic
3
- Version: 0.4.6
3
+ Version: 0.4.8
4
4
  Summary: A Python package for creating AI Assistants and AI Agents with Vectara
5
5
  Home-page: https://github.com/vectara/py-vectara-agentic
6
6
  Author: Ofer Mendelevitch
@@ -16,34 +16,35 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
16
  Requires-Python: >=3.10
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
- Requires-Dist: llama-index==0.13.3
20
- Requires-Dist: llama-index-core==0.13.3
21
- Requires-Dist: llama-index-workflows==1.3.0
22
- Requires-Dist: llama-index-cli==0.5.0
23
- Requires-Dist: llama-index-indices-managed-vectara==0.5.0
24
- Requires-Dist: llama-index-llms-openai==0.5.4
25
- Requires-Dist: llama-index-llms-openai-like==0.5.0
26
- Requires-Dist: llama-index-llms-anthropic==0.8.5
27
- Requires-Dist: llama-index-llms-together==0.4.0
28
- Requires-Dist: llama-index-llms-groq==0.4.0
29
- Requires-Dist: llama-index-llms-cohere==0.6.0
30
- Requires-Dist: llama-index-llms-google-genai==0.3.0
19
+ Requires-Dist: llama-index==0.14.2
20
+ Requires-Dist: llama-index-core==0.14.2
21
+ Requires-Dist: llama-index-workflows==2.2.2
22
+ Requires-Dist: llama-index-cli==0.5.1
23
+ Requires-Dist: llama-index-indices-managed-vectara==0.5.1
24
+ Requires-Dist: llama-index-llms-openai==0.5.6
25
+ Requires-Dist: llama-index-llms-openai-like==0.5.1
26
+ Requires-Dist: llama-index-llms-anthropic==0.8.6
27
+ Requires-Dist: llama-index-llms-together==0.4.1
28
+ Requires-Dist: llama-index-llms-groq==0.4.1
29
+ Requires-Dist: llama-index-llms-cohere==0.6.1
30
+ Requires-Dist: llama-index-llms-google-genai==0.5.0
31
+ Requires-Dist: llama-index-llms-baseten==0.1.4
31
32
  Requires-Dist: google_genai>=1.31.0
32
- Requires-Dist: llama-index-llms-bedrock-converse==0.8.2
33
- Requires-Dist: llama-index-tools-yahoo-finance==0.4.0
34
- Requires-Dist: llama-index-tools-arxiv==0.4.0
35
- Requires-Dist: llama-index-tools-database==0.4.0
36
- Requires-Dist: llama-index-tools-google==0.6.0
37
- Requires-Dist: llama-index-tools-tavily_research==0.4.0
38
- Requires-Dist: llama_index.tools.brave_search==0.4.0
39
- Requires-Dist: llama-index-tools-neo4j==0.4.0
40
- Requires-Dist: llama-index-tools-waii==0.4.0
41
- Requires-Dist: llama-index-graph-stores-kuzu==0.9.0
42
- Requires-Dist: llama-index-tools-salesforce==0.4.0
43
- Requires-Dist: llama-index-tools-slack==0.4.0
44
- Requires-Dist: llama-index-tools-exa==0.4.0
45
- Requires-Dist: llama-index-tools-wikipedia==0.4.0
46
- Requires-Dist: llama-index-tools-bing-search==0.4.0
33
+ Requires-Dist: llama-index-llms-bedrock-converse==0.9.2
34
+ Requires-Dist: llama-index-tools-yahoo-finance==0.4.1
35
+ Requires-Dist: llama-index-tools-arxiv==0.4.1
36
+ Requires-Dist: llama-index-tools-database==0.4.1
37
+ Requires-Dist: llama-index-tools-google==0.6.2
38
+ Requires-Dist: llama-index-tools-tavily_research==0.4.1
39
+ Requires-Dist: llama_index.tools.brave_search==0.4.1
40
+ Requires-Dist: llama-index-tools-neo4j==0.4.1
41
+ Requires-Dist: llama-index-tools-waii==0.4.1
42
+ Requires-Dist: llama-index-graph-stores-kuzu==0.9.1
43
+ Requires-Dist: llama-index-tools-salesforce==0.4.1
44
+ Requires-Dist: llama-index-tools-slack==0.4.1
45
+ Requires-Dist: llama-index-tools-exa==0.4.1
46
+ Requires-Dist: llama-index-tools-wikipedia==0.4.1
47
+ Requires-Dist: llama-index-tools-bing-search==0.4.1
47
48
  Requires-Dist: openai>=1.99.3
48
49
  Requires-Dist: tavily-python>=0.7.10
49
50
  Requires-Dist: exa-py>=1.14.20
@@ -736,13 +737,13 @@ If you want to use `agent`, `tools`, `llm` or `verbose` in other events (that ar
736
737
  the `Context` of the Workflow as follows:
737
738
 
738
739
  ```python
739
- await ctx.set("agent", ev.agent)
740
+ await ctx.store.set("agent", ev.agent)
740
741
  ```
741
742
 
742
743
  and then in any other event you can pull that agent object with
743
744
 
744
745
  ```python
745
- agent = await ctx.get("agent")
746
+ agent = await ctx.store.get("agent")
746
747
  ```
747
748
 
748
749
  Similarly you can reuse the `llm`, `tools` or `verbose` arguments within other nodes in the workflow.
@@ -886,7 +887,7 @@ The `AgentConfig` object may include the following items:
886
887
  - `main_llm_provider` and `tool_llm_provider`: the LLM provider for main agent and for the tools. Valid values are `OPENAI`, `ANTHROPIC`, `TOGETHER`, `GROQ`, `COHERE`, `BEDROCK`, `GEMINI` (default: `OPENAI`).
887
888
 
888
889
  > **Note:** Fireworks AI support has been removed. If you were using Fireworks, please migrate to one of the supported providers listed above.
889
- - `main_llm_model_name` and `tool_llm_model_name`: agent model name for agent and tools (default depends on provider: OpenAI uses gpt-4.1-mini, Gemini uses gemini-2.5-flash-lite).
890
+ - `main_llm_model_name` and `tool_llm_model_name`: agent model name for agent and tools (default depends on provider: OpenAI uses gpt-4.1-mini, Anthropic uses claude-sonnet-4-0, Gemini uses models/gemini-2.5-flash, Together.AI uses deepseek-ai/DeepSeek-V3, GROQ uses openai/gpt-oss-20b, Bedrock uses us.anthropic.claude-sonnet-4-20250514-v1:0, Cohere uses command-a-03-2025).
890
891
  - `observer`: the observer type; should be `ARIZE_PHOENIX` or if undefined no observation framework will be used.
891
892
  - `endpoint_api_key`: a secret key if using the API endpoint option (defaults to `dev-api-key`)
892
893
 
@@ -8,11 +8,11 @@ tests/test_agent_fallback_memory.py,sha256=1LoRHxUM767bGmCeusPlGubX_pIeP5KxIABRw
8
8
  tests/test_agent_memory_consistency.py,sha256=D8ivCGp5reJyOK7Q6wDiZlv3bKX4-SEchnqocyib1Po,8966
9
9
  tests/test_agent_type.py,sha256=hx0FPKhhP-zaT2Z7MYlrZw10srws8VUQgBoZk2-vUxY,5155
10
10
  tests/test_api_endpoint.py,sha256=PrfV6kWvq5icm3zLgrse9isBsR6EkwfUtSdz1ADSUUs,5115
11
- tests/test_bedrock.py,sha256=4qBip3plouQkHTRU01_sYebop6fiVe3Fnx5vjkMl3H4,2003
11
+ tests/test_bedrock.py,sha256=iyg5bwzYjWrVo7-pofAWBOqAPaJVrnjZlEo2oY5Pjmo,7524
12
12
  tests/test_fallback.py,sha256=LQtnYoK-NohJL3D3pQnlY0yrIGs2B25j6B3gX3wGM1c,3073
13
- tests/test_gemini.py,sha256=HVTWmwPFxJ-hjketCkbXa_mOyWXpE-1dG9fu47z00bU,1632
14
- tests/test_groq.py,sha256=BikJ0AV5-k3kvTUbila9bmIKv2iJy3TQm-Kb_Y23kYw,3378
15
- tests/test_openai.py,sha256=Uc8wPovmeLgmMItV4OOya6rWlSv7Omre1_B11ajpozU,5396
13
+ tests/test_gemini.py,sha256=7DMoTjjFV4wnncy0E-Vn3cEHhWWIhsmgCvVI29CnJ7o,4820
14
+ tests/test_groq.py,sha256=Es8yrYFv14wOXd9oVLbxZWpfll_irgIcBZjkXMOALYY,13773
15
+ tests/test_openai.py,sha256=p_z4IjoVKTBJpO-7lThY7MMVIlCDnh63neaMNqSu5mM,10894
16
16
  tests/test_private_llm.py,sha256=O5sQfZ_NgE2S1-YJ6eMRn1Gz17XkRjEk9O0iHGACRu0,2752
17
17
  tests/test_react_error_handling.py,sha256=xAozh77qNSvaEzMDHjw2blbDNVUY-5qfvBldD_YHCQQ,11198
18
18
  tests/test_react_memory.py,sha256=3YAPhrWAjmDcT2jm2IfxBx2LSWJGkpYUhWQiVt-qXFs,10177
@@ -23,37 +23,37 @@ tests/test_serialization.py,sha256=DJZ2E_K54t8INwZR0Q8gS1wi-MGbLIheOBcbRmZNcro,5
23
23
  tests/test_session_memory.py,sha256=hnADl59agjpXySY-CBjw6sDPn3s6JketIK6XbLZsLzU,9691
24
24
  tests/test_streaming.py,sha256=r-kj6DOB7sn2mkEv_8msGgIYeKXEtWgrDF2qTtCqnZY,1828
25
25
  tests/test_together.py,sha256=zR06GoFU0549VYKZRZ5z8bbpvQ6l_vLA0bYLp5SokuU,4770
26
- tests/test_tools.py,sha256=vvi3FC4SDOwpyKJUFOWCWJ5i3Y474FrKFHnZpo4aFQg,13643
26
+ tests/test_tools.py,sha256=W_V5NHjRfEX_Lrh5jNhhZbeKsRdFVUJNTOKfX1hkJGg,19638
27
27
  tests/test_vectara_llms.py,sha256=WoswpfPGhQlBXyOijn5EBX0F2NL1Oq3FDB4wxu7mwXs,2485
28
28
  tests/test_vhc.py,sha256=jVojp8ZUDF60yJaYp5pBRdAdNYK1hhhPz_RTmlTEm4g,1980
29
29
  tests/test_workflow.py,sha256=43YUF-0YDbiiJrTSYjnyqrC4gvHYuHQp7uuzV2jMdTE,3553
30
30
  vectara_agentic/__init__.py,sha256=CfS3QR4drKygcTcyH5zUUDuXXQ3WZtTCytz8W4-loeE,1077
31
31
  vectara_agentic/_callback.py,sha256=hYbHU_3sMF4-h0YMierZ9EEWspakNixk7wXAAWztlmU,15364
32
32
  vectara_agentic/_observability.py,sha256=rApfdndB2R021iM0xG4MumTSDX1Ba6qbNM0N_AOTbR0,4884
33
- vectara_agentic/_version.py,sha256=Pe3UjAetTNxa1VnM12B-MP-q9vn6iHFH5ACP829y97g,65
34
- vectara_agentic/agent.py,sha256=5eC4BkMPWep8c_LIHSB2N1CvsFLdX6qPAhIpgLR08Gc,49125
33
+ vectara_agentic/_version.py,sha256=HdETEw_rKB6UiQdWIaY4Mzr6I6euLT4jkv9Yc7sX4m0,65
34
+ vectara_agentic/agent.py,sha256=KZFOfOFtxvQdd0RknMvlipVcguOTGjpZRFofRrhZzHk,49160
35
35
  vectara_agentic/agent_config.py,sha256=njqEX2qHJjAp2KpNuJglgZhyWXPK74wjIjBPACD6w7w,4074
36
36
  vectara_agentic/agent_endpoint.py,sha256=E_AF-YwxaKqd1-p43X62e1e4ugwOWKIyNq4RWOfsO7A,7402
37
37
  vectara_agentic/db_tools.py,sha256=nVZkpGdG63ooGngjX9g7YWyBZRtYMDpvzNasbO696nM,11498
38
- vectara_agentic/llm_utils.py,sha256=CqrBOMf9sL-CD0xD-yiEYNyduZV4GBho4e518z_pt5s,9422
39
- vectara_agentic/sub_query_workflow.py,sha256=1y0fBoUem4i-R34QYlSzcMwM8YhmYgj6S_bWynUtL6w,13001
38
+ vectara_agentic/llm_utils.py,sha256=RyM5AvDc5jmBhF9x4WUMgZRohGuyleYsNBSP6zwRmUk,9399
39
+ vectara_agentic/sub_query_workflow.py,sha256=2pOhE_O6nUw4moQK11QOo7ATcMjlkiJBhlz7T0oumFI,13199
40
40
  vectara_agentic/tool_utils.py,sha256=whnQlk9coeIt01sqUnKnzUorefgn96yWqhtRfHxNL84,25921
41
- vectara_agentic/tools.py,sha256=PsHpcSj6QRycueSUsggzwEgAouG0d7gCOjc_ZB0_bgk,37597
41
+ vectara_agentic/tools.py,sha256=7uW7O1JPeCfN2ndSbxNeynEd3L_NvfwfD2PM2zqix6k,41612
42
42
  vectara_agentic/tools_catalog.py,sha256=p6eRram-diJyMz5dZI703auSAm97FfW5wLAMyz_2sB0,4634
43
43
  vectara_agentic/types.py,sha256=qKkK8vRNiLvEcMInMyOClK2bD7iFlrWGTkl3fGC6Xic,6117
44
44
  vectara_agentic/utils.py,sha256=R9HitEG5K3Q_p2M_teosT181OUxkhs1-hnj98qDYGbE,2545
45
45
  vectara_agentic/agent_core/__init__.py,sha256=R3KGbSOiY21FOjbeQ_GyIi6uR9Rz7PTfudO9RjSuEZQ,722
46
46
  vectara_agentic/agent_core/factory.py,sha256=Nmmhl98r2Op4qJwq9cgfy7DfrWI62JUfxFXHoBxKHBo,14158
47
- vectara_agentic/agent_core/prompts.py,sha256=al7SF5pNzOG-KK0lCtTS-HCwVStB6yvE34dgHWJQ_bA,9989
47
+ vectara_agentic/agent_core/prompts.py,sha256=wLOKfA-YZQojR-aCJ8gM_tJAIeePReEykrG_vgJPmls,10087
48
48
  vectara_agentic/agent_core/serialization.py,sha256=Npfcgm9j8B0ck74uIUgqTGljt8HTpcMCdnWV6CKYBZE,11878
49
- vectara_agentic/agent_core/streaming.py,sha256=OmjTNEJ25SR788ltyvekVpP83hnv6Tw-MixCwOUK9Kc,26452
49
+ vectara_agentic/agent_core/streaming.py,sha256=r1-gcyb0R2Ri42VKsrS9hXpb2n2qKC9GA76L2jyYBkQ,25707
50
50
  vectara_agentic/agent_core/utils/__init__.py,sha256=y5Xf0IH-5TRxMBRA9IyhmWnGZOVIyqV45P6lX4c2Qsc,762
51
51
  vectara_agentic/agent_core/utils/hallucination.py,sha256=XmV7tW-MBN9BrzM79zu0T7zaWil7fIkNQjLfDZE43v4,5312
52
52
  vectara_agentic/agent_core/utils/logging.py,sha256=-Ll8iUelml92WuhNWScuY6H-RheyZOTBHNxXQ1UGy0M,1701
53
53
  vectara_agentic/agent_core/utils/schemas.py,sha256=4sEyQ-_z-eZJzgxCJf62AuBgV7RN1Azc9mLPPlj6IWg,2769
54
54
  vectara_agentic/agent_core/utils/tools.py,sha256=JQmiWldJd2_9SXE9cCEF9u4ESLJr15-JemORAAZbgnk,5068
55
- vectara_agentic-0.4.6.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
56
- vectara_agentic-0.4.6.dist-info/METADATA,sha256=WonZYKu6_-97YYqnaJVaGURz6IcQpn_M-di5wd8tjVY,38906
57
- vectara_agentic-0.4.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
58
- vectara_agentic-0.4.6.dist-info/top_level.txt,sha256=Y7TQTFdOYGYodQRltUGRieZKIYuzeZj2kHqAUpfCUfg,22
59
- vectara_agentic-0.4.6.dist-info/RECORD,,
55
+ vectara_agentic-0.4.8.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
56
+ vectara_agentic-0.4.8.dist-info/METADATA,sha256=Gnacxm8PWh-8PMmdLO3ZnneNpgDEo2ohNQ52yyKExLo,39161
57
+ vectara_agentic-0.4.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
58
+ vectara_agentic-0.4.8.dist-info/top_level.txt,sha256=Y7TQTFdOYGYodQRltUGRieZKIYuzeZj2kHqAUpfCUfg,22
59
+ vectara_agentic-0.4.8.dist-info/RECORD,,