selectools 0.16.3__tar.gz → 0.16.4__tar.gz

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.
Files changed (113) hide show
  1. {selectools-0.16.3/src/selectools.egg-info → selectools-0.16.4}/PKG-INFO +1 -1
  2. {selectools-0.16.3 → selectools-0.16.4}/pyproject.toml +1 -1
  3. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/__init__.py +1 -1
  4. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/agent/core.py +31 -4
  5. {selectools-0.16.3 → selectools-0.16.4/src/selectools.egg-info}/PKG-INFO +1 -1
  6. {selectools-0.16.3 → selectools-0.16.4}/LICENSE +0 -0
  7. {selectools-0.16.3 → selectools-0.16.4}/README.md +0 -0
  8. {selectools-0.16.3 → selectools-0.16.4}/setup.cfg +0 -0
  9. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/agent/__init__.py +0 -0
  10. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/agent/config.py +0 -0
  11. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/analytics.py +0 -0
  12. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/audit.py +0 -0
  13. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/cache.py +0 -0
  14. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/cache_redis.py +0 -0
  15. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/cli.py +0 -0
  16. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/coherence.py +0 -0
  17. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/embeddings/__init__.py +0 -0
  18. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/embeddings/anthropic.py +0 -0
  19. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/embeddings/cohere.py +0 -0
  20. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/embeddings/gemini.py +0 -0
  21. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/embeddings/openai.py +0 -0
  22. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/embeddings/provider.py +0 -0
  23. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/entity_memory.py +0 -0
  24. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/env.py +0 -0
  25. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/exceptions.py +0 -0
  26. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/guardrails/__init__.py +0 -0
  27. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/guardrails/base.py +0 -0
  28. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/guardrails/format.py +0 -0
  29. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/guardrails/length.py +0 -0
  30. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/guardrails/pii.py +0 -0
  31. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/guardrails/pipeline.py +0 -0
  32. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/guardrails/topic.py +0 -0
  33. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/guardrails/toxicity.py +0 -0
  34. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/knowledge.py +0 -0
  35. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/knowledge_graph.py +0 -0
  36. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/memory.py +0 -0
  37. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/models.py +0 -0
  38. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/observer.py +0 -0
  39. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/parser.py +0 -0
  40. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/policy.py +0 -0
  41. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/pricing.py +0 -0
  42. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/prompt.py +0 -0
  43. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/providers/__init__.py +0 -0
  44. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/providers/anthropic_provider.py +0 -0
  45. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/providers/base.py +0 -0
  46. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/providers/fallback.py +0 -0
  47. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/providers/gemini_provider.py +0 -0
  48. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/providers/ollama_provider.py +0 -0
  49. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/providers/openai_provider.py +0 -0
  50. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/providers/stubs.py +0 -0
  51. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/rag/__init__.py +0 -0
  52. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/rag/bm25.py +0 -0
  53. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/rag/chunking.py +0 -0
  54. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/rag/hybrid.py +0 -0
  55. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/rag/loaders.py +0 -0
  56. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/rag/reranker.py +0 -0
  57. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/rag/stores/__init__.py +0 -0
  58. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/rag/stores/chroma.py +0 -0
  59. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/rag/stores/memory.py +0 -0
  60. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/rag/stores/pinecone.py +0 -0
  61. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/rag/stores/sqlite.py +0 -0
  62. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/rag/tools.py +0 -0
  63. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/rag/vector_store.py +0 -0
  64. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/security.py +0 -0
  65. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/sessions.py +0 -0
  66. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/structured.py +0 -0
  67. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/toolbox/__init__.py +0 -0
  68. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/toolbox/data_tools.py +0 -0
  69. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/toolbox/datetime_tools.py +0 -0
  70. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/toolbox/file_tools.py +0 -0
  71. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/toolbox/memory_tools.py +0 -0
  72. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/toolbox/text_tools.py +0 -0
  73. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/toolbox/web_tools.py +0 -0
  74. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/tools/__init__.py +0 -0
  75. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/tools/base.py +0 -0
  76. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/tools/decorators.py +0 -0
  77. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/tools/loader.py +0 -0
  78. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/tools/registry.py +0 -0
  79. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/trace.py +0 -0
  80. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/types.py +0 -0
  81. {selectools-0.16.3 → selectools-0.16.4}/src/selectools/usage.py +0 -0
  82. {selectools-0.16.3 → selectools-0.16.4}/src/selectools.egg-info/SOURCES.txt +0 -0
  83. {selectools-0.16.3 → selectools-0.16.4}/src/selectools.egg-info/dependency_links.txt +0 -0
  84. {selectools-0.16.3 → selectools-0.16.4}/src/selectools.egg-info/entry_points.txt +0 -0
  85. {selectools-0.16.3 → selectools-0.16.4}/src/selectools.egg-info/requires.txt +0 -0
  86. {selectools-0.16.3 → selectools-0.16.4}/src/selectools.egg-info/top_level.txt +0 -0
  87. {selectools-0.16.3 → selectools-0.16.4}/tests/test_audit.py +0 -0
  88. {selectools-0.16.3 → selectools-0.16.4}/tests/test_cache.py +0 -0
  89. {selectools-0.16.3 → selectools-0.16.4}/tests/test_cache_redis.py +0 -0
  90. {selectools-0.16.3 → selectools-0.16.4}/tests/test_cli.py +0 -0
  91. {selectools-0.16.3 → selectools-0.16.4}/tests/test_coherence.py +0 -0
  92. {selectools-0.16.3 → selectools-0.16.4}/tests/test_consolidation_regression.py +0 -0
  93. {selectools-0.16.3 → selectools-0.16.4}/tests/test_entity_memory.py +0 -0
  94. {selectools-0.16.3 → selectools-0.16.4}/tests/test_env.py +0 -0
  95. {selectools-0.16.3 → selectools-0.16.4}/tests/test_guardrails.py +0 -0
  96. {selectools-0.16.3 → selectools-0.16.4}/tests/test_knowledge.py +0 -0
  97. {selectools-0.16.3 → selectools-0.16.4}/tests/test_knowledge_graph.py +0 -0
  98. {selectools-0.16.3 → selectools-0.16.4}/tests/test_memory.py +0 -0
  99. {selectools-0.16.3 → selectools-0.16.4}/tests/test_memory_async.py +0 -0
  100. {selectools-0.16.3 → selectools-0.16.4}/tests/test_memory_boundary.py +0 -0
  101. {selectools-0.16.3 → selectools-0.16.4}/tests/test_memory_integration.py +0 -0
  102. {selectools-0.16.3 → selectools-0.16.4}/tests/test_parser.py +0 -0
  103. {selectools-0.16.3 → selectools-0.16.4}/tests/test_policy.py +0 -0
  104. {selectools-0.16.3 → selectools-0.16.4}/tests/test_prompt.py +0 -0
  105. {selectools-0.16.3 → selectools-0.16.4}/tests/test_routing_mode.py +0 -0
  106. {selectools-0.16.3 → selectools-0.16.4}/tests/test_security.py +0 -0
  107. {selectools-0.16.3 → selectools-0.16.4}/tests/test_sessions.py +0 -0
  108. {selectools-0.16.3 → selectools-0.16.4}/tests/test_sessions_edge_cases.py +0 -0
  109. {selectools-0.16.3 → selectools-0.16.4}/tests/test_sessions_redis.py +0 -0
  110. {selectools-0.16.3 → selectools-0.16.4}/tests/test_structured.py +0 -0
  111. {selectools-0.16.3 → selectools-0.16.4}/tests/test_summarize_on_trim.py +0 -0
  112. {selectools-0.16.3 → selectools-0.16.4}/tests/test_trace.py +0 -0
  113. {selectools-0.16.3 → selectools-0.16.4}/tests/test_v016_regression.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: selectools
3
- Version: 0.16.3
3
+ Version: 0.16.4
4
4
  Summary: Production-ready AI agents with tool calling, structured output, execution traces, and RAG. Provider-agnostic (OpenAI, Anthropic, Gemini, Ollama) with fallback chains, batch processing, tool policies, streaming, caching, and cost tracking.
5
5
  Author-email: John <johnnichev@gmail.com>
6
6
  License-Expression: LGPL-3.0-or-later
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "selectools"
7
- version = "0.16.3"
7
+ version = "0.16.4"
8
8
  description = "Production-ready AI agents with tool calling, structured output, execution traces, and RAG. Provider-agnostic (OpenAI, Anthropic, Gemini, Ollama) with fallback chains, batch processing, tool policies, streaming, caching, and cost tracking."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -1,6 +1,6 @@
1
1
  """Public exports for the selectools package."""
2
2
 
3
- __version__ = "0.16.3"
3
+ __version__ = "0.16.4"
4
4
 
5
5
  # Import submodules (lazy loading for optional dependencies)
6
6
  from . import embeddings, guardrails, models, rag, toolbox
@@ -548,10 +548,12 @@ class Agent:
548
548
  self._wire_fallback_observer(run_id)
549
549
  self._notify_observers("on_run_start", run_id, messages, self._system_prompt)
550
550
 
551
- # Input guardrails
552
- for msg in messages:
553
- if msg.role == Role.USER and msg.content:
554
- msg.content = self._run_input_guardrails(msg.content, trace)
551
+ # Input guardrails (operate on copies to avoid mutating caller's objects)
552
+ if self.config.guardrails and self.config.guardrails.input:
553
+ messages = [copy.copy(msg) for msg in messages]
554
+ for msg in messages:
555
+ if msg.role == Role.USER and msg.content:
556
+ msg.content = self._run_input_guardrails(msg.content, trace)
555
557
 
556
558
  # Memory / session loading
557
559
  if self.memory:
@@ -962,6 +964,7 @@ class Agent:
962
964
  prompt: str,
963
965
  stream_handler: Optional[Callable[[str], None]] = None,
964
966
  response_format: Optional[ResponseFormat] = None,
967
+ parent_run_id: Optional[str] = None,
965
968
  ) -> AgentResult:
966
969
  """
967
970
  Send a single user prompt and return the agent's response.
@@ -975,6 +978,7 @@ class Agent:
975
978
  response_format: Optional Pydantic model class or JSON Schema dict.
976
979
  When provided the LLM is instructed to return valid JSON and
977
980
  the result is validated. Access via ``result.parsed``.
981
+ parent_run_id: Optional run-ID of a parent agent for trace linking.
978
982
 
979
983
  Returns:
980
984
  AgentResult with the response and metadata.
@@ -988,6 +992,7 @@ class Agent:
988
992
  [Message(role=Role.USER, content=prompt)],
989
993
  stream_handler=stream_handler,
990
994
  response_format=response_format,
995
+ parent_run_id=parent_run_id,
991
996
  )
992
997
 
993
998
  async def aask(
@@ -995,6 +1000,7 @@ class Agent:
995
1000
  prompt: str,
996
1001
  stream_handler: Optional[Callable[[str], None]] = None,
997
1002
  response_format: Optional[ResponseFormat] = None,
1003
+ parent_run_id: Optional[str] = None,
998
1004
  ) -> AgentResult:
999
1005
  """
1000
1006
  Async version of :meth:`ask`.
@@ -1003,6 +1009,7 @@ class Agent:
1003
1009
  prompt: Plain-text question or instruction.
1004
1010
  stream_handler: Optional callback for streaming responses.
1005
1011
  response_format: Optional Pydantic model class or JSON Schema dict.
1012
+ parent_run_id: Optional run-ID of a parent agent for trace linking.
1006
1013
 
1007
1014
  Returns:
1008
1015
  AgentResult with the response and metadata.
@@ -1015,6 +1022,7 @@ class Agent:
1015
1022
  [Message(role=Role.USER, content=prompt)],
1016
1023
  stream_handler=stream_handler,
1017
1024
  response_format=response_format,
1025
+ parent_run_id=parent_run_id,
1018
1026
  )
1019
1027
 
1020
1028
  def batch(
@@ -1284,6 +1292,7 @@ class Agent:
1284
1292
  response_text,
1285
1293
  trace=ctx.trace,
1286
1294
  run_id=ctx.run_id,
1295
+ user_text_for_coherence=ctx.user_text_for_coherence,
1287
1296
  )
1288
1297
  ctx.last_tool_name = _last_name
1289
1298
  ctx.last_tool_args = _last_args
@@ -1717,6 +1726,7 @@ class Agent:
1717
1726
  response_text: str,
1718
1727
  trace: Optional[AgentTrace] = None,
1719
1728
  run_id: Optional[str] = None,
1729
+ user_text_for_coherence: str = "",
1720
1730
  ) -> tuple:
1721
1731
  """Execute multiple tool calls concurrently using ThreadPoolExecutor.
1722
1732
 
@@ -1749,6 +1759,10 @@ class Agent:
1749
1759
  if policy_error:
1750
1760
  return _Result(tc, policy_error, True, 0.0, tool, 0)
1751
1761
 
1762
+ coherence_error = self._check_coherence(user_text_for_coherence, tool_name, parameters)
1763
+ if coherence_error:
1764
+ return _Result(tc, coherence_error, True, 0.0, tool, 0)
1765
+
1752
1766
  call_id = tc.id or ""
1753
1767
  start = time.time()
1754
1768
  self._call_hook("on_tool_start", tool_name, parameters)
@@ -1771,6 +1785,7 @@ class Agent:
1771
1785
 
1772
1786
  try:
1773
1787
  result = self._execute_tool_with_timeout(tool, parameters, chunk_cb)
1788
+ result = self._screen_tool_result(tool_name, result)
1774
1789
  dur = time.time() - start
1775
1790
  self._call_hook("on_tool_end", tool_name, result, dur)
1776
1791
  if run_id:
@@ -1880,6 +1895,7 @@ class Agent:
1880
1895
  response_text: str,
1881
1896
  trace: Optional[AgentTrace] = None,
1882
1897
  run_id: Optional[str] = None,
1898
+ user_text_for_coherence: str = "",
1883
1899
  ) -> tuple:
1884
1900
  """Execute multiple tool calls concurrently using asyncio.gather.
1885
1901
 
@@ -1913,6 +1929,12 @@ class Agent:
1913
1929
  if policy_error:
1914
1930
  return _Result(tc, policy_error, True, 0.0, tool, 0)
1915
1931
 
1932
+ coherence_error = await self._acheck_coherence(
1933
+ user_text_for_coherence, tool_name, parameters
1934
+ )
1935
+ if coherence_error:
1936
+ return _Result(tc, coherence_error, True, 0.0, tool, 0)
1937
+
1916
1938
  start = time.time()
1917
1939
  self._call_hook("on_tool_start", tool_name, parameters)
1918
1940
  if run_id:
@@ -1934,6 +1956,7 @@ class Agent:
1934
1956
 
1935
1957
  try:
1936
1958
  result = await self._aexecute_tool_with_timeout(tool, parameters, chunk_cb)
1959
+ result = self._screen_tool_result(tool_name, result)
1937
1960
  dur = time.time() - start
1938
1961
  self._call_hook("on_tool_end", tool_name, result, dur)
1939
1962
  if run_id:
@@ -2136,6 +2159,8 @@ class Agent:
2136
2159
  timeout=self.config.request_timeout,
2137
2160
  ),
2138
2161
  )
2162
+ if _usage:
2163
+ self.usage.add_usage(_usage, tool_name=None)
2139
2164
  self._call_hook("on_llm_end", response_msg.content, _usage)
2140
2165
  self._notify_observers("on_llm_end", ctx.run_id, response_msg.content, _usage)
2141
2166
  if _usage:
@@ -2276,6 +2301,7 @@ class Agent:
2276
2301
  full_content,
2277
2302
  trace=ctx.trace,
2278
2303
  run_id=ctx.run_id,
2304
+ user_text_for_coherence=ctx.user_text_for_coherence,
2279
2305
  )
2280
2306
  ctx.last_tool_name = _last_name
2281
2307
  ctx.last_tool_args = _last_args
@@ -2613,6 +2639,7 @@ class Agent:
2613
2639
  response_text,
2614
2640
  trace=ctx.trace,
2615
2641
  run_id=ctx.run_id,
2642
+ user_text_for_coherence=ctx.user_text_for_coherence,
2616
2643
  )
2617
2644
  ctx.last_tool_name = _last_name
2618
2645
  ctx.last_tool_args = _last_args
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: selectools
3
- Version: 0.16.3
3
+ Version: 0.16.4
4
4
  Summary: Production-ready AI agents with tool calling, structured output, execution traces, and RAG. Provider-agnostic (OpenAI, Anthropic, Gemini, Ollama) with fallback chains, batch processing, tool policies, streaming, caching, and cost tracking.
5
5
  Author-email: John <johnnichev@gmail.com>
6
6
  License-Expression: LGPL-3.0-or-later
File without changes
File without changes
File without changes