selectools 1.0.0__tar.gz → 1.0.1__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 (323) hide show
  1. {selectools-1.0.0/src/selectools.egg-info → selectools-1.0.1}/PKG-INFO +3 -1
  2. {selectools-1.0.0 → selectools-1.0.1}/README.md +2 -0
  3. {selectools-1.0.0 → selectools-1.0.1}/pyproject.toml +4 -3
  4. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/__init__.py +1 -1
  5. selectools-1.0.1/src/selectools/_time.py +42 -0
  6. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/agent/_lifecycle.py +1 -1
  7. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/agent/_memory_manager.py +0 -1
  8. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/agent/_provider_caller.py +1 -1
  9. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/agent/_tool_executor.py +2 -2
  10. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/agent/config.py +1 -1
  11. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/agent/config_groups.py +1 -4
  12. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/agent/core.py +1 -1
  13. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/audit.py +0 -1
  14. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/cache_semantic.py +1 -1
  15. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/checkpoint_postgres.py +3 -5
  16. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/compose.py +1 -2
  17. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/evals/history.py +1 -1
  18. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/evals/pairwise.py +1 -5
  19. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/evals/serve.py +1 -5
  20. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/evals/templates.py +1 -2
  21. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/guardrails/pipeline.py +1 -1
  22. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/knowledge.py +7 -7
  23. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/knowledge_store_redis.py +3 -2
  24. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/knowledge_store_supabase.py +3 -2
  25. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/mcp/bridge.py +1 -1
  26. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/mcp/client.py +1 -2
  27. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/mcp/config.py +1 -1
  28. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/mcp/multi.py +1 -1
  29. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/mcp/server.py +1 -2
  30. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/observe/langfuse.py +1 -1
  31. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/observe/otel.py +1 -1
  32. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/observe/trace_store.py +4 -6
  33. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/observer.py +1 -1
  34. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/orchestration/checkpoint.py +4 -3
  35. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/orchestration/graph.py +2 -5
  36. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/orchestration/node.py +1 -3
  37. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/orchestration/state.py +3 -3
  38. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/orchestration/supervisor.py +3 -7
  39. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/patterns/debate.py +2 -3
  40. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/patterns/plan_and_execute.py +2 -3
  41. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/patterns/reflective.py +2 -3
  42. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/patterns/team_lead.py +2 -3
  43. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/providers/_openai_compat.py +1 -1
  44. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/providers/anthropic_provider.py +0 -1
  45. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/providers/azure_openai_provider.py +1 -1
  46. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/providers/fallback.py +1 -3
  47. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/providers/ollama_provider.py +1 -2
  48. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/rag/bm25.py +0 -6
  49. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/rag/hybrid.py +0 -16
  50. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/rag/loaders.py +1 -1
  51. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/rag/stores/faiss.py +2 -2
  52. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/rag/stores/memory.py +0 -1
  53. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/rag/stores/pinecone.py +4 -1
  54. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/rag/stores/qdrant.py +1 -3
  55. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/scheduler.py +1 -1
  56. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/serve/app.py +1 -3
  57. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/serve/cli.py +1 -1
  58. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/serve/models.py +0 -25
  59. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/sessions.py +2 -6
  60. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/datetime_tools.py +0 -1
  61. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/tools/base.py +0 -1
  62. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/trace.py +1 -1
  63. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/unified_memory.py +2 -3
  64. {selectools-1.0.0 → selectools-1.0.1/src/selectools.egg-info}/PKG-INFO +3 -1
  65. {selectools-1.0.0 → selectools-1.0.1}/src/selectools.egg-info/SOURCES.txt +2 -0
  66. selectools-1.0.1/tests/test_time.py +66 -0
  67. {selectools-1.0.0 → selectools-1.0.1}/LICENSE +0 -0
  68. {selectools-1.0.0 → selectools-1.0.1}/setup.cfg +0 -0
  69. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/_async_utils.py +0 -0
  70. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/_json_utils.py +0 -0
  71. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/_ssrf.py +0 -0
  72. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/a2a/__init__.py +0 -0
  73. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/a2a/client.py +0 -0
  74. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/a2a/server.py +0 -0
  75. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/a2a/types.py +0 -0
  76. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/agent/__init__.py +0 -0
  77. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/agent/_planning.py +0 -0
  78. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/analytics.py +0 -0
  79. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/cache.py +0 -0
  80. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/cache_redis.py +0 -0
  81. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/cancellation.py +0 -0
  82. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/coherence.py +0 -0
  83. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/embeddings/__init__.py +0 -0
  84. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/embeddings/anthropic.py +0 -0
  85. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/embeddings/cohere.py +0 -0
  86. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/embeddings/gemini.py +0 -0
  87. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/embeddings/openai.py +0 -0
  88. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/embeddings/provider.py +0 -0
  89. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/entity_memory.py +0 -0
  90. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/env.py +0 -0
  91. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/evals/__init__.py +0 -0
  92. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/evals/__main__.py +0 -0
  93. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/evals/badge.py +0 -0
  94. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/evals/dataset.py +0 -0
  95. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/evals/evaluators.py +0 -0
  96. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/evals/generator.py +0 -0
  97. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/evals/html.py +0 -0
  98. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/evals/junit.py +0 -0
  99. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/evals/llm_evaluators.py +0 -0
  100. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/evals/regression.py +0 -0
  101. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/evals/report.py +0 -0
  102. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/evals/snapshot.py +0 -0
  103. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/evals/suite.py +0 -0
  104. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/evals/types.py +0 -0
  105. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/exceptions.py +0 -0
  106. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/guardrails/__init__.py +0 -0
  107. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/guardrails/base.py +0 -0
  108. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/guardrails/format.py +0 -0
  109. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/guardrails/injection.py +0 -0
  110. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/guardrails/length.py +0 -0
  111. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/guardrails/pii.py +0 -0
  112. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/guardrails/topic.py +0 -0
  113. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/guardrails/toxicity.py +0 -0
  114. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/knowledge_backends.py +0 -0
  115. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/knowledge_graph.py +0 -0
  116. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/knowledge_sanitizers.py +0 -0
  117. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/loop_detection.py +0 -0
  118. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/mcp/__init__.py +0 -0
  119. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/mcp/_loop.py +0 -0
  120. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/memory.py +0 -0
  121. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/models.py +0 -0
  122. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/observe/__init__.py +0 -0
  123. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/orchestration/__init__.py +0 -0
  124. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/parser.py +0 -0
  125. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/patterns/__init__.py +0 -0
  126. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/pending.py +0 -0
  127. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/pipeline.py +0 -0
  128. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/policy.py +0 -0
  129. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/pricing.py +0 -0
  130. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/prompt.py +0 -0
  131. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/providers/__init__.py +0 -0
  132. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/providers/base.py +0 -0
  133. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/providers/gemini_provider.py +0 -0
  134. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/providers/litellm_provider.py +0 -0
  135. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/providers/openai_provider.py +0 -0
  136. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/providers/router.py +0 -0
  137. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/providers/stubs.py +0 -0
  138. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/rag/__init__.py +0 -0
  139. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/rag/chunking.py +0 -0
  140. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/rag/reranker.py +0 -0
  141. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/rag/stores/__init__.py +0 -0
  142. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/rag/stores/chroma.py +0 -0
  143. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/rag/stores/pgvector.py +0 -0
  144. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/rag/stores/sqlite.py +0 -0
  145. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/rag/tools.py +0 -0
  146. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/rag/vector_store.py +0 -0
  147. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/results.py +0 -0
  148. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/security.py +0 -0
  149. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/serve/__init__.py +0 -0
  150. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/serve/_starlette_app.py +0 -0
  151. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/serve/_static/builder.css +0 -0
  152. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/serve/_static/builder.html +0 -0
  153. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/serve/_static/builder.js +0 -0
  154. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/serve/api.py +0 -0
  155. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/serve/builder.py +0 -0
  156. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/serve/playground.py +0 -0
  157. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/stability.py +0 -0
  158. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/structured.py +0 -0
  159. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/templates/__init__.py +0 -0
  160. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/templates/code_reviewer.py +0 -0
  161. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/templates/customer_support.py +0 -0
  162. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/templates/data_analyst.py +0 -0
  163. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/templates/rag_chatbot.py +0 -0
  164. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/templates/research_assistant.py +0 -0
  165. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/token_estimation.py +0 -0
  166. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/__init__.py +0 -0
  167. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/browser_tools.py +0 -0
  168. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/calculator_tools.py +0 -0
  169. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/code_tools.py +0 -0
  170. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/data_tools.py +0 -0
  171. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/db_tools.py +0 -0
  172. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/discord_tools.py +0 -0
  173. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/email_tools.py +0 -0
  174. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/file_tools.py +0 -0
  175. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/github_tools.py +0 -0
  176. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/image_tools.py +0 -0
  177. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/linear_tools.py +0 -0
  178. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/memory_tools.py +0 -0
  179. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/notion_tools.py +0 -0
  180. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/pdf_tools.py +0 -0
  181. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/reasoning_tools.py +0 -0
  182. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/s3_tools.py +0 -0
  183. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/search_tools.py +0 -0
  184. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/slack_tools.py +0 -0
  185. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/text_tools.py +0 -0
  186. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/toolbox/web_tools.py +0 -0
  187. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/tools/__init__.py +0 -0
  188. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/tools/decorators.py +0 -0
  189. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/tools/loader.py +0 -0
  190. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/tools/registry.py +0 -0
  191. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/types.py +0 -0
  192. {selectools-1.0.0 → selectools-1.0.1}/src/selectools/usage.py +0 -0
  193. {selectools-1.0.0 → selectools-1.0.1}/src/selectools.egg-info/dependency_links.txt +0 -0
  194. {selectools-1.0.0 → selectools-1.0.1}/src/selectools.egg-info/entry_points.txt +0 -0
  195. {selectools-1.0.0 → selectools-1.0.1}/src/selectools.egg-info/requires.txt +0 -0
  196. {selectools-1.0.0 → selectools-1.0.1}/src/selectools.egg-info/top_level.txt +0 -0
  197. {selectools-1.0.0 → selectools-1.0.1}/tests/test_a2a.py +0 -0
  198. {selectools-1.0.0 → selectools-1.0.1}/tests/test_agent_api.py +0 -0
  199. {selectools-1.0.0 → selectools-1.0.1}/tests/test_agent_hitl.py +0 -0
  200. {selectools-1.0.0 → selectools-1.0.1}/tests/test_approval_gate.py +0 -0
  201. {selectools-1.0.0 → selectools-1.0.1}/tests/test_architecture.py +0 -0
  202. {selectools-1.0.0 → selectools-1.0.1}/tests/test_async_observers.py +0 -0
  203. {selectools-1.0.0 → selectools-1.0.1}/tests/test_audit.py +0 -0
  204. {selectools-1.0.0 → selectools-1.0.1}/tests/test_bake_window_hunt.py +0 -0
  205. {selectools-1.0.0 → selectools-1.0.1}/tests/test_budget.py +0 -0
  206. {selectools-1.0.0 → selectools-1.0.1}/tests/test_bug_hunt_batch1_core.py +0 -0
  207. {selectools-1.0.0 → selectools-1.0.1}/tests/test_bug_hunt_batch1_security.py +0 -0
  208. {selectools-1.0.0 → selectools-1.0.1}/tests/test_bug_hunt_batch1_tools.py +0 -0
  209. {selectools-1.0.0 → selectools-1.0.1}/tests/test_bug_hunt_regression.py +0 -0
  210. {selectools-1.0.0 → selectools-1.0.1}/tests/test_cache.py +0 -0
  211. {selectools-1.0.0 → selectools-1.0.1}/tests/test_cache_redis.py +0 -0
  212. {selectools-1.0.0 → selectools-1.0.1}/tests/test_cancellation.py +0 -0
  213. {selectools-1.0.0 → selectools-1.0.1}/tests/test_checkpoint_postgres.py +0 -0
  214. {selectools-1.0.0 → selectools-1.0.1}/tests/test_coherence.py +0 -0
  215. {selectools-1.0.0 → selectools-1.0.1}/tests/test_concurrency_smoke.py +0 -0
  216. {selectools-1.0.0 → selectools-1.0.1}/tests/test_consolidation_regression.py +0 -0
  217. {selectools-1.0.0 → selectools-1.0.1}/tests/test_conversation_branching.py +0 -0
  218. {selectools-1.0.0 → selectools-1.0.1}/tests/test_coverage_orchestration.py +0 -0
  219. {selectools-1.0.0 → selectools-1.0.1}/tests/test_document_loaders_extended.py +0 -0
  220. {selectools-1.0.0 → selectools-1.0.1}/tests/test_e2e_langfuse_observer.py +0 -0
  221. {selectools-1.0.0 → selectools-1.0.1}/tests/test_e2e_multimodal.py +0 -0
  222. {selectools-1.0.0 → selectools-1.0.1}/tests/test_e2e_otel_observer.py +0 -0
  223. {selectools-1.0.0 → selectools-1.0.1}/tests/test_e2e_v0_21_0_apps.py +0 -0
  224. {selectools-1.0.0 → selectools-1.0.1}/tests/test_e2e_v0_21_0_simulations.py +0 -0
  225. {selectools-1.0.0 → selectools-1.0.1}/tests/test_entity_memory.py +0 -0
  226. {selectools-1.0.0 → selectools-1.0.1}/tests/test_env.py +0 -0
  227. {selectools-1.0.0 → selectools-1.0.1}/tests/test_evals.py +0 -0
  228. {selectools-1.0.0 → selectools-1.0.1}/tests/test_evals_advanced.py +0 -0
  229. {selectools-1.0.0 → selectools-1.0.1}/tests/test_evals_cli.py +0 -0
  230. {selectools-1.0.0 → selectools-1.0.1}/tests/test_evals_e2e.py +0 -0
  231. {selectools-1.0.0 → selectools-1.0.1}/tests/test_evals_final.py +0 -0
  232. {selectools-1.0.0 → selectools-1.0.1}/tests/test_evals_hardening.py +0 -0
  233. {selectools-1.0.0 → selectools-1.0.1}/tests/test_evals_html_report.py +0 -0
  234. {selectools-1.0.0 → selectools-1.0.1}/tests/test_evals_new_evaluators.py +0 -0
  235. {selectools-1.0.0 → selectools-1.0.1}/tests/test_evals_ralph_bugs.py +0 -0
  236. {selectools-1.0.0 → selectools-1.0.1}/tests/test_evals_release.py +0 -0
  237. {selectools-1.0.0 → selectools-1.0.1}/tests/test_evals_serve.py +0 -0
  238. {selectools-1.0.0 → selectools-1.0.1}/tests/test_evals_v017_features.py +0 -0
  239. {selectools-1.0.0 → selectools-1.0.1}/tests/test_evals_v0191.py +0 -0
  240. {selectools-1.0.0 → selectools-1.0.1}/tests/test_features_in_graph.py +0 -0
  241. {selectools-1.0.0 → selectools-1.0.1}/tests/test_final_coverage_a.py +0 -0
  242. {selectools-1.0.0 → selectools-1.0.1}/tests/test_final_coverage_b.py +0 -0
  243. {selectools-1.0.0 → selectools-1.0.1}/tests/test_guardrails.py +0 -0
  244. {selectools-1.0.0 → selectools-1.0.1}/tests/test_guardrails_injection.py +0 -0
  245. {selectools-1.0.0 → selectools-1.0.1}/tests/test_hardening.py +0 -0
  246. {selectools-1.0.0 → selectools-1.0.1}/tests/test_knowledge.py +0 -0
  247. {selectools-1.0.0 → selectools-1.0.1}/tests/test_knowledge_backend.py +0 -0
  248. {selectools-1.0.0 → selectools-1.0.1}/tests/test_knowledge_backend_redis.py +0 -0
  249. {selectools-1.0.0 → selectools-1.0.1}/tests/test_knowledge_backend_supabase.py +0 -0
  250. {selectools-1.0.0 → selectools-1.0.1}/tests/test_knowledge_graph.py +0 -0
  251. {selectools-1.0.0 → selectools-1.0.1}/tests/test_knowledge_sanitizers.py +0 -0
  252. {selectools-1.0.0 → selectools-1.0.1}/tests/test_knowledge_store_redis.py +0 -0
  253. {selectools-1.0.0 → selectools-1.0.1}/tests/test_knowledge_store_supabase.py +0 -0
  254. {selectools-1.0.0 → selectools-1.0.1}/tests/test_knowledge_stores.py +0 -0
  255. {selectools-1.0.0 → selectools-1.0.1}/tests/test_knowledge_stores_error_handling.py +0 -0
  256. {selectools-1.0.0 → selectools-1.0.1}/tests/test_langfuse_observer.py +0 -0
  257. {selectools-1.0.0 → selectools-1.0.1}/tests/test_loop_detection.py +0 -0
  258. {selectools-1.0.0 → selectools-1.0.1}/tests/test_mcp.py +0 -0
  259. {selectools-1.0.0 → selectools-1.0.1}/tests/test_mcp_coverage.py +0 -0
  260. {selectools-1.0.0 → selectools-1.0.1}/tests/test_memory.py +0 -0
  261. {selectools-1.0.0 → selectools-1.0.1}/tests/test_memory_async.py +0 -0
  262. {selectools-1.0.0 → selectools-1.0.1}/tests/test_memory_boundary.py +0 -0
  263. {selectools-1.0.0 → selectools-1.0.1}/tests/test_memory_integration.py +0 -0
  264. {selectools-1.0.0 → selectools-1.0.1}/tests/test_model_switching.py +0 -0
  265. {selectools-1.0.0 → selectools-1.0.1}/tests/test_multi_agent_edge_cases.py +0 -0
  266. {selectools-1.0.0 → selectools-1.0.1}/tests/test_multimodal.py +0 -0
  267. {selectools-1.0.0 → selectools-1.0.1}/tests/test_orchestration_checkpoint.py +0 -0
  268. {selectools-1.0.0 → selectools-1.0.1}/tests/test_orchestration_e2e.py +0 -0
  269. {selectools-1.0.0 → selectools-1.0.1}/tests/test_orchestration_evals.py +0 -0
  270. {selectools-1.0.0 → selectools-1.0.1}/tests/test_orchestration_graph.py +0 -0
  271. {selectools-1.0.0 → selectools-1.0.1}/tests/test_orchestration_integration.py +0 -0
  272. {selectools-1.0.0 → selectools-1.0.1}/tests/test_orchestration_primitives.py +0 -0
  273. {selectools-1.0.0 → selectools-1.0.1}/tests/test_orchestration_supervisor.py +0 -0
  274. {selectools-1.0.0 → selectools-1.0.1}/tests/test_otel_observer.py +0 -0
  275. {selectools-1.0.0 → selectools-1.0.1}/tests/test_parser.py +0 -0
  276. {selectools-1.0.0 → selectools-1.0.1}/tests/test_patterns.py +0 -0
  277. {selectools-1.0.0 → selectools-1.0.1}/tests/test_pending.py +0 -0
  278. {selectools-1.0.0 → selectools-1.0.1}/tests/test_pending_redis_smoke.py +0 -0
  279. {selectools-1.0.0 → selectools-1.0.1}/tests/test_phase1_design_patterns.py +0 -0
  280. {selectools-1.0.0 → selectools-1.0.1}/tests/test_pipeline.py +0 -0
  281. {selectools-1.0.0 → selectools-1.0.1}/tests/test_pipeline_coverage.py +0 -0
  282. {selectools-1.0.0 → selectools-1.0.1}/tests/test_policy.py +0 -0
  283. {selectools-1.0.0 → selectools-1.0.1}/tests/test_prompt.py +0 -0
  284. {selectools-1.0.0 → selectools-1.0.1}/tests/test_prompt_compression.py +0 -0
  285. {selectools-1.0.0 → selectools-1.0.1}/tests/test_property_based.py +0 -0
  286. {selectools-1.0.0 → selectools-1.0.1}/tests/test_reasoning_strategy.py +0 -0
  287. {selectools-1.0.0 → selectools-1.0.1}/tests/test_remaining_coverage.py +0 -0
  288. {selectools-1.0.0 → selectools-1.0.1}/tests/test_results.py +0 -0
  289. {selectools-1.0.0 → selectools-1.0.1}/tests/test_routing_mode.py +0 -0
  290. {selectools-1.0.0 → selectools-1.0.1}/tests/test_scheduler.py +0 -0
  291. {selectools-1.0.0 → selectools-1.0.1}/tests/test_security.py +0 -0
  292. {selectools-1.0.0 → selectools-1.0.1}/tests/test_semantic_cache.py +0 -0
  293. {selectools-1.0.0 → selectools-1.0.1}/tests/test_serve_app_coverage.py +0 -0
  294. {selectools-1.0.0 → selectools-1.0.1}/tests/test_serve_cli.py +0 -0
  295. {selectools-1.0.0 → selectools-1.0.1}/tests/test_sessions.py +0 -0
  296. {selectools-1.0.0 → selectools-1.0.1}/tests/test_sessions_dynamodb.py +0 -0
  297. {selectools-1.0.0 → selectools-1.0.1}/tests/test_sessions_edge_cases.py +0 -0
  298. {selectools-1.0.0 → selectools-1.0.1}/tests/test_sessions_mongo.py +0 -0
  299. {selectools-1.0.0 → selectools-1.0.1}/tests/test_sessions_redis.py +0 -0
  300. {selectools-1.0.0 → selectools-1.0.1}/tests/test_sessions_supabase.py +0 -0
  301. {selectools-1.0.0 → selectools-1.0.1}/tests/test_simple_observer.py +0 -0
  302. {selectools-1.0.0 → selectools-1.0.1}/tests/test_simulation_evals.py +0 -0
  303. {selectools-1.0.0 → selectools-1.0.1}/tests/test_ssrf.py +0 -0
  304. {selectools-1.0.0 → selectools-1.0.1}/tests/test_stability.py +0 -0
  305. {selectools-1.0.0 → selectools-1.0.1}/tests/test_starlette_app.py +0 -0
  306. {selectools-1.0.0 → selectools-1.0.1}/tests/test_structured.py +0 -0
  307. {selectools-1.0.0 → selectools-1.0.1}/tests/test_structured_config.py +0 -0
  308. {selectools-1.0.0 → selectools-1.0.1}/tests/test_structured_tool_results.py +0 -0
  309. {selectools-1.0.0 → selectools-1.0.1}/tests/test_summarize_on_trim.py +0 -0
  310. {selectools-1.0.0 → selectools-1.0.1}/tests/test_templates_coverage.py +0 -0
  311. {selectools-1.0.0 → selectools-1.0.1}/tests/test_terminal_actions.py +0 -0
  312. {selectools-1.0.0 → selectools-1.0.1}/tests/test_token_estimation.py +0 -0
  313. {selectools-1.0.0 → selectools-1.0.1}/tests/test_tool_caching.py +0 -0
  314. {selectools-1.0.0 → selectools-1.0.1}/tests/test_tool_result_compression.py +0 -0
  315. {selectools-1.0.0 → selectools-1.0.1}/tests/test_trace.py +0 -0
  316. {selectools-1.0.0 → selectools-1.0.1}/tests/test_trace_html.py +0 -0
  317. {selectools-1.0.0 → selectools-1.0.1}/tests/test_trace_store.py +0 -0
  318. {selectools-1.0.0 → selectools-1.0.1}/tests/test_unified_memory.py +0 -0
  319. {selectools-1.0.0 → selectools-1.0.1}/tests/test_unified_memory_config.py +0 -0
  320. {selectools-1.0.0 → selectools-1.0.1}/tests/test_v016_regression.py +0 -0
  321. {selectools-1.0.0 → selectools-1.0.1}/tests/test_v019_features.py +0 -0
  322. {selectools-1.0.0 → selectools-1.0.1}/tests/test_visual_builder.py +0 -0
  323. {selectools-1.0.0 → selectools-1.0.1}/tests/test_yaml_config.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: selectools
3
- Version: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: Production-ready Python framework for AI agents with multi-agent graphs, hybrid RAG, guardrails, audit logging, 50 evaluators, and a visual builder. Supports OpenAI, Anthropic, Gemini, Ollama. By NichevLabs.
5
5
  Author-email: John Nichev <johnnichev@gmail.com>
6
6
  Maintainer-email: NichevLabs <support@nichevlabs.com>
@@ -103,6 +103,8 @@ An open-source project from **[NichevLabs](https://nichevlabs.com)**.
103
103
 
104
104
  **Multi-agent orchestration in plain Python.** Build agent graphs, compose pipelines with `|`, deploy with one command. No DSL, no compile step, no paid debugger. Works with OpenAI, Anthropic, Gemini, and Ollama.
105
105
 
106
+ > 🎉 **selectools is 1.0 — stable.** The public API is frozen; `@stable` symbols carry a 2-minor compatibility promise. Python 3.10+. See [What's New in v1.0](#whats-new-in-v10).
107
+
106
108
  ### 3 Ways to Build
107
109
 
108
110
  ```python
@@ -16,6 +16,8 @@ An open-source project from **[NichevLabs](https://nichevlabs.com)**.
16
16
 
17
17
  **Multi-agent orchestration in plain Python.** Build agent graphs, compose pipelines with `|`, deploy with one command. No DSL, no compile step, no paid debugger. Works with OpenAI, Anthropic, Gemini, and Ollama.
18
18
 
19
+ > 🎉 **selectools is 1.0 — stable.** The public API is frozen; `@stable` symbols carry a 2-minor compatibility promise. Python 3.10+. See [What's New in v1.0](#whats-new-in-v10).
20
+
19
21
  ### 3 Ways to Build
20
22
 
21
23
  ```python
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "selectools"
7
- version = "1.0.0"
7
+ version = "1.0.1"
8
8
  description = "Production-ready Python framework for AI agents with multi-agent graphs, hybrid RAG, guardrails, audit logging, 50 evaluators, and a visual builder. Supports OpenAI, Anthropic, Gemini, Ollama. By NichevLabs."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -154,15 +154,16 @@ ignore = [
154
154
  "E501", # line too long (handled by formatter)
155
155
  "E402", # module-level import not at top
156
156
  "E721", # type comparison with == (allowed; legacy test pattern)
157
- "F401", # unused imports (common in __init__.py re-exports)
158
157
  "F541", # f-string without placeholder
159
- "F841", # local variable assigned but never used
160
158
  "B011", # do not call assert False
161
159
  "B023", # function definition does not bind loop variable
162
160
  "B904", # raise without `from` in except (TODO: fix pre-existing violations)
163
161
  ]
164
162
 
165
163
  [tool.ruff.lint.per-file-ignores]
164
+ # F401 unused-import is expected in __init__.py re-export hubs (the public-API
165
+ # surface). Everywhere else, unused imports and unused locals are real findings.
166
+ "**/__init__.py" = ["F401"]
166
167
  "tests/*" = ["B"]
167
168
  "examples/*" = ["B", "F"]
168
169
  "scripts/*" = ["B", "F"]
@@ -1,6 +1,6 @@
1
1
  """Public exports for the selectools package."""
2
2
 
3
- __version__ = "1.0.0"
3
+ __version__ = "1.0.1"
4
4
 
5
5
  # Import submodules (lazy loading for optional dependencies)
6
6
  from . import embeddings, evals, guardrails, models, observe, patterns, rag, toolbox
@@ -0,0 +1,42 @@
1
+ """Internal time helpers.
2
+
3
+ Centralizes ISO-8601 timestamp parsing so every persistence backend handles a
4
+ trailing ``Z`` (UTC designator) the same way.
5
+
6
+ ``datetime.fromisoformat`` did not accept the ``Z`` suffix until Python 3.11.
7
+ On Python 3.10 (the project's minimum) a ``Z``-suffixed timestamp such as
8
+ ``"2026-06-15T12:00:00Z"`` raises ``ValueError``. Postgres/Supabase/Redis and
9
+ other stores routinely return that form, so parsing it inline crashed the
10
+ knowledge and checkpoint loaders on 3.10. ``parse_iso`` normalizes the suffix
11
+ before delegating, so the same code works on every supported interpreter.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ from datetime import datetime, timezone
17
+ from typing import Union
18
+
19
+
20
+ def parse_iso(value: Union[str, datetime]) -> datetime:
21
+ """Parse an ISO-8601 timestamp, tolerating a trailing ``Z`` (UTC).
22
+
23
+ Accepts either a string or an already-parsed ``datetime`` (returned as-is,
24
+ so callers reading columns that may already be typed do not need their own
25
+ ``isinstance`` guard). Timezone awareness is preserved exactly as encoded:
26
+ an offset-bearing string (including ``Z``) yields an aware datetime; a naive
27
+ string yields a naive datetime. Use :func:`ensure_aware` when a guaranteed
28
+ aware value is required.
29
+ """
30
+ if isinstance(value, datetime):
31
+ return value
32
+ s = str(value)
33
+ if s.endswith("Z"):
34
+ s = s[:-1] + "+00:00"
35
+ return datetime.fromisoformat(s)
36
+
37
+
38
+ def ensure_aware(dt: datetime, *, tz: timezone = timezone.utc) -> datetime:
39
+ """Attach ``tz`` (default UTC) to a naive datetime; pass aware ones through."""
40
+ if dt.tzinfo is None:
41
+ return dt.replace(tzinfo=tz)
42
+ return dt
@@ -8,7 +8,7 @@ import threading
8
8
  from typing import TYPE_CHECKING, Any, Optional, cast
9
9
 
10
10
  if TYPE_CHECKING:
11
- from ..memory import ConversationMemory
11
+ pass
12
12
 
13
13
  logger = logging.getLogger(__name__)
14
14
 
@@ -9,7 +9,6 @@ from ..trace import AgentTrace, StepType, TraceStep
9
9
  from ..types import Message, Role
10
10
 
11
11
  if TYPE_CHECKING:
12
- from ..memory import ConversationMemory
13
12
  from .core import _RunContext
14
13
 
15
14
 
@@ -6,7 +6,7 @@ import asyncio
6
6
  import threading
7
7
  import time
8
8
  from concurrent.futures import ThreadPoolExecutor
9
- from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple
9
+ from typing import TYPE_CHECKING, Callable, List, Optional, Tuple
10
10
 
11
11
  # Module-level singleton for running sync provider calls in an async context.
12
12
  # Creating a new ThreadPoolExecutor per call (inside a retry loop) wastes
@@ -57,8 +57,8 @@ def _get_parallel_dispatch_executor() -> ThreadPoolExecutor:
57
57
 
58
58
 
59
59
  from .._async_utils import run_in_executor_copyctx
60
- from ..coherence import CoherenceResult, acheck_coherence, check_coherence
61
- from ..policy import ApprovalRequest, PolicyDecision, PolicyResult, ToolPolicy
60
+ from ..coherence import acheck_coherence, check_coherence
61
+ from ..policy import ApprovalRequest, PolicyDecision, PolicyResult
62
62
  from ..security import screen_output as screen_tool_output
63
63
  from ..trace import StepType, TraceStep
64
64
  from ..types import Message, Role
@@ -7,7 +7,7 @@ from __future__ import annotations
7
7
  from dataclasses import dataclass, field
8
8
  from typing import TYPE_CHECKING, Any, Callable, Coroutine, Dict, List, Optional, Union
9
9
 
10
- from ..stability import beta, stable
10
+ from ..stability import stable
11
11
 
12
12
  if TYPE_CHECKING:
13
13
  from ..cache import Cache
@@ -24,23 +24,20 @@ Usage::
24
24
  from __future__ import annotations
25
25
 
26
26
  from dataclasses import dataclass, field
27
- from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Union
27
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
28
28
 
29
29
  from ..stability import stable
30
30
 
31
31
  if TYPE_CHECKING:
32
- from ..cache import Cache
33
32
  from ..cancellation import CancellationToken
34
33
  from ..entity_memory import EntityMemory
35
34
  from ..guardrails import GuardrailsPipeline
36
35
  from ..knowledge import KnowledgeMemory
37
36
  from ..knowledge_graph import KnowledgeGraphMemory
38
- from ..observer import AgentObserver
39
37
  from ..policy import ToolPolicy
40
38
  from ..providers.base import Provider
41
39
  from ..sessions import SessionStore
42
40
  from ..unified_memory import UnifiedMemory
43
- from ..usage import AgentUsage
44
41
 
45
42
 
46
43
  @stable
@@ -17,7 +17,7 @@ from .._async_utils import aclosing, run_in_executor_copyctx
17
17
  from ..analytics import AgentAnalytics
18
18
  from ..parser import ToolCallParser
19
19
  from ..prompt import PromptBuilder
20
- from ..providers.base import Provider, ProviderError
20
+ from ..providers.base import Provider
21
21
  from ..providers.openai_provider import OpenAIProvider
22
22
  from ..results import Artifact, _begin_artifact_collection
23
23
  from ..stability import beta, deprecated, stable
@@ -18,7 +18,6 @@ import hashlib
18
18
  import json
19
19
  import os
20
20
  import threading
21
- import time
22
21
  from datetime import datetime, timezone
23
22
  from enum import Enum
24
23
  from typing import Any, Dict, List, Optional
@@ -12,7 +12,7 @@ from __future__ import annotations
12
12
  import math
13
13
  import threading
14
14
  import time
15
- from dataclasses import dataclass, field
15
+ from dataclasses import dataclass
16
16
  from typing import TYPE_CHECKING, Any, List, Optional, Tuple
17
17
 
18
18
  from .cache import CacheStats
@@ -20,9 +20,9 @@ import json
20
20
  import re
21
21
  import threading
22
22
  import uuid
23
- from datetime import datetime, timezone
24
- from typing import Any, Dict, List, Optional, Tuple
23
+ from typing import List, Tuple
25
24
 
25
+ from ._time import parse_iso
26
26
  from .orchestration.checkpoint import (
27
27
  CheckpointMetadata,
28
28
  _deserialize_checkpoint,
@@ -137,9 +137,7 @@ class PostgresCheckpointStore:
137
137
  step=r[2],
138
138
  node_name=r[3],
139
139
  interrupted=r[4],
140
- created_at=(
141
- r[5] if isinstance(r[5], datetime) else datetime.fromisoformat(str(r[5]))
142
- ),
140
+ created_at=parse_iso(r[5]),
143
141
  )
144
142
  for r in rows
145
143
  ]
@@ -21,11 +21,10 @@ Usage::
21
21
 
22
22
  from __future__ import annotations
23
23
 
24
- from typing import Any, Callable, List, Optional, Sequence
24
+ from typing import Any, Callable, List, Optional
25
25
 
26
26
  from .stability import beta
27
27
  from .tools.base import Tool
28
- from .tools.decorators import tool as tool_decorator
29
28
 
30
29
 
31
30
  @beta
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  import json
6
6
  from dataclasses import dataclass, field
7
7
  from pathlib import Path
8
- from typing import Any, Dict, List, Optional, Union
8
+ from typing import Any, List, Optional, Union
9
9
 
10
10
  from ..stability import beta
11
11
 
@@ -2,18 +2,14 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- import time
6
- import uuid
7
5
  from dataclasses import dataclass, field
8
6
  from typing import Any, Dict, List, Optional
9
7
 
10
- from .. import __version__
11
8
  from ..agent import Agent
12
9
  from ..stability import beta
13
- from .evaluators import DEFAULT_EVALUATORS
14
10
  from .report import EvalReport
15
11
  from .suite import EvalSuite
16
- from .types import CaseResult, CaseVerdict, EvalMetadata, TestCase
12
+ from .types import CaseResult, CaseVerdict, TestCase
17
13
 
18
14
 
19
15
  @beta
@@ -2,16 +2,12 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- import html
6
5
  import json
7
6
  import threading
8
- import time
9
7
  from http.server import HTTPServer, SimpleHTTPRequestHandler
10
- from io import BytesIO
11
- from typing import Any, Callable, Dict, List, Optional
8
+ from typing import Any, Dict
12
9
 
13
10
  from ..stability import beta
14
- from .types import CaseVerdict
15
11
 
16
12
 
17
13
  class _DashboardHandler(SimpleHTTPRequestHandler):
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Any, List, Optional
5
+ from typing import List, Optional
6
6
 
7
7
  from ..agent import Agent
8
8
  from ..stability import beta
@@ -10,7 +10,6 @@ from .evaluators import (
10
10
  ContainsEvaluator,
11
11
  CustomEvaluator,
12
12
  InjectionResistanceEvaluator,
13
- JsonValidityEvaluator,
14
13
  LengthEvaluator,
15
14
  PerformanceEvaluator,
16
15
  PIILeakEvaluator,
@@ -10,7 +10,7 @@ from __future__ import annotations
10
10
 
11
11
  import logging
12
12
  from dataclasses import dataclass, field
13
- from typing import List, Optional
13
+ from typing import List
14
14
 
15
15
  from selectools.stability import stable
16
16
 
@@ -29,7 +29,6 @@ import logging
29
29
  import os
30
30
  import sqlite3
31
31
  import threading
32
- import time
33
32
  import uuid
34
33
  from dataclasses import dataclass, field
35
34
  from datetime import datetime, timedelta, timezone
@@ -45,6 +44,7 @@ from typing import (
45
44
  runtime_checkable,
46
45
  )
47
46
 
47
+ from ._time import parse_iso
48
48
  from .knowledge_sanitizers import dedupe_against
49
49
  from .stability import beta, register_stability, stable
50
50
 
@@ -291,10 +291,10 @@ class FileKnowledgeStore:
291
291
  continue
292
292
  try:
293
293
  d = json.loads(line)
294
- created_at = datetime.fromisoformat(d["created_at"])
294
+ created_at = parse_iso(d["created_at"])
295
295
  if created_at.tzinfo is None:
296
296
  created_at = created_at.replace(tzinfo=timezone.utc)
297
- updated_at = datetime.fromisoformat(d["updated_at"])
297
+ updated_at = parse_iso(d["updated_at"])
298
298
  if updated_at.tzinfo is None:
299
299
  updated_at = updated_at.replace(tzinfo=timezone.utc)
300
300
  entries.append(
@@ -467,10 +467,10 @@ class SQLiteKnowledgeStore:
467
467
  )
468
468
 
469
469
  def _row_to_entry(self, row: tuple) -> KnowledgeEntry:
470
- created_at = datetime.fromisoformat(row[6])
470
+ created_at = parse_iso(row[6])
471
471
  if created_at.tzinfo is None:
472
472
  created_at = created_at.replace(tzinfo=timezone.utc)
473
- updated_at = datetime.fromisoformat(row[7])
473
+ updated_at = parse_iso(row[7])
474
474
  if updated_at.tzinfo is None:
475
475
  updated_at = updated_at.replace(tzinfo=timezone.utc)
476
476
  return KnowledgeEntry(
@@ -564,7 +564,7 @@ class SQLiteKnowledgeStore:
564
564
  if persistent:
565
565
  continue
566
566
  if ttl is not None:
567
- created_dt = datetime.fromisoformat(created)
567
+ created_dt = parse_iso(created)
568
568
  if created_dt.tzinfo is None:
569
569
  created_dt = created_dt.replace(tzinfo=timezone.utc)
570
570
  if now > created_dt + timedelta(days=ttl):
@@ -572,7 +572,7 @@ class SQLiteKnowledgeStore:
572
572
  removed += 1
573
573
  continue
574
574
  if max_age_days is not None:
575
- created_dt = datetime.fromisoformat(created)
575
+ created_dt = parse_iso(created)
576
576
  if created_dt.tzinfo is None:
577
577
  created_dt = created_dt.replace(tzinfo=timezone.utc)
578
578
  if now > created_dt + timedelta(days=max_age_days):
@@ -13,6 +13,7 @@ import logging
13
13
  from datetime import datetime, timedelta, timezone
14
14
  from typing import Any, Dict, List, Optional
15
15
 
16
+ from ._time import parse_iso
16
17
  from .knowledge import KnowledgeEntry
17
18
  from .stability import beta
18
19
 
@@ -69,10 +70,10 @@ class RedisKnowledgeStore:
69
70
 
70
71
  @staticmethod
71
72
  def _dict_to_entry(data: Dict[str, str]) -> KnowledgeEntry:
72
- created_at = datetime.fromisoformat(data["created_at"])
73
+ created_at = parse_iso(data["created_at"])
73
74
  if created_at.tzinfo is None:
74
75
  created_at = created_at.replace(tzinfo=timezone.utc)
75
- updated_at = datetime.fromisoformat(data["updated_at"])
76
+ updated_at = parse_iso(data["updated_at"])
76
77
  if updated_at.tzinfo is None:
77
78
  updated_at = updated_at.replace(tzinfo=timezone.utc)
78
79
  return KnowledgeEntry(
@@ -13,6 +13,7 @@ import logging
13
13
  from datetime import datetime, timedelta, timezone
14
14
  from typing import Any, Dict, List, Optional
15
15
 
16
+ from ._time import parse_iso
16
17
  from .knowledge import KnowledgeEntry
17
18
  from .stability import beta
18
19
 
@@ -69,10 +70,10 @@ class SupabaseKnowledgeStore:
69
70
  metadata = row.get("metadata", {})
70
71
  if isinstance(metadata, str):
71
72
  metadata = json.loads(metadata)
72
- created_at = datetime.fromisoformat(row["created_at"])
73
+ created_at = parse_iso(row["created_at"])
73
74
  if created_at.tzinfo is None:
74
75
  created_at = created_at.replace(tzinfo=timezone.utc)
75
- updated_at = datetime.fromisoformat(row["updated_at"])
76
+ updated_at = parse_iso(row["updated_at"])
76
77
  if updated_at.tzinfo is None:
77
78
  updated_at = updated_at.replace(tzinfo=timezone.utc)
78
79
  return KnowledgeEntry(
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Any, Callable, Dict, List, Optional
5
+ from typing import Any, Dict, List
6
6
 
7
7
  from ..tools.base import Tool, ToolParameter
8
8
 
@@ -4,8 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import asyncio
6
6
  import time
7
- from contextlib import asynccontextmanager
8
- from typing import Any, AsyncGenerator, Dict, List, Optional
7
+ from typing import Any, Dict, List, Optional
9
8
 
10
9
  from ..stability import beta
11
10
  from ..tools.base import Tool
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import os
6
6
  from dataclasses import dataclass, field
7
- from typing import Any, Dict, List, Optional
7
+ from typing import Dict, List, Optional
8
8
  from urllib.parse import urlparse
9
9
 
10
10
  from ..stability import beta
@@ -3,7 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import logging
6
- from typing import Any, Dict, List, Optional, Set
6
+ from typing import Any, Dict, List, Set
7
7
 
8
8
  from ..stability import beta
9
9
  from ..tools.base import Tool
@@ -3,8 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import asyncio
6
- import inspect
7
- from typing import Any, Dict, List, Optional
6
+ from typing import Any, List
8
7
 
9
8
  from .. import __version__
10
9
  from ..stability import beta
@@ -14,7 +14,7 @@ from __future__ import annotations
14
14
  import logging
15
15
  import os
16
16
  import threading
17
- from typing import Any, Dict, List, Optional
17
+ from typing import Any, Dict, Optional
18
18
 
19
19
  from ..observer import AgentObserver
20
20
  from ..stability import beta
@@ -14,7 +14,7 @@ from __future__ import annotations
14
14
  import logging
15
15
  import threading
16
16
  import time
17
- from typing import Any, Dict, List, Optional
17
+ from typing import Any, Dict
18
18
 
19
19
  from ..observer import AgentObserver
20
20
  from ..stability import beta
@@ -7,16 +7,14 @@ Three backends: InMemory (dev), SQLite (production), JSONL (export/archive).
7
7
  from __future__ import annotations
8
8
 
9
9
  import json
10
- import os
11
10
  import sqlite3
12
11
  import threading
13
- import time
14
- import uuid
15
- from dataclasses import asdict, dataclass, field
12
+ from dataclasses import dataclass, field
16
13
  from datetime import datetime, timezone
17
14
  from pathlib import Path
18
15
  from typing import Any, Dict, Iterator, List, Optional, Protocol, runtime_checkable
19
16
 
17
+ from .._time import parse_iso
20
18
  from ..stability import beta, register_stability
21
19
  from ..trace import AgentTrace
22
20
 
@@ -285,7 +283,7 @@ class SQLiteTraceStore:
285
283
  run_id=run_id,
286
284
  steps=steps,
287
285
  total_ms=total_ms,
288
- created_at=datetime.fromisoformat(created_at),
286
+ created_at=parse_iso(created_at),
289
287
  metadata=meta,
290
288
  )
291
289
 
@@ -369,7 +367,7 @@ class JSONLTraceStore:
369
367
  run_id=entry.get("run_id", ""),
370
368
  steps=entry.get("steps", 0),
371
369
  total_ms=entry.get("total_ms", 0.0),
372
- created_at=datetime.fromisoformat(entry.get("created_at", "2000-01-01T00:00:00+00:00")),
370
+ created_at=parse_iso(entry.get("created_at", "2000-01-01T00:00:00+00:00")),
373
371
  metadata=entry.get("metadata", {}),
374
372
  )
375
373
 
@@ -35,7 +35,7 @@ import logging
35
35
  import time
36
36
  from typing import Any, Callable, Dict, List, Optional
37
37
 
38
- from .stability import beta, stable
38
+ from .stability import stable
39
39
  from .types import AgentResult, Message
40
40
  from .usage import UsageStats
41
41
 
@@ -30,8 +30,9 @@ import threading
30
30
  import uuid
31
31
  from dataclasses import dataclass
32
32
  from datetime import datetime, timezone
33
- from typing import Dict, List, Optional, Protocol, Tuple, runtime_checkable
33
+ from typing import Dict, List, Protocol, Tuple, runtime_checkable
34
34
 
35
+ from .._time import parse_iso
35
36
  from ..stability import register_stability, stable
36
37
  from .state import GraphState
37
38
 
@@ -257,7 +258,7 @@ class FileCheckpointStore:
257
258
  step=m["step"],
258
259
  node_name=m.get("node_name", ""),
259
260
  interrupted=m.get("interrupted", False),
260
- created_at=datetime.fromisoformat(m["created_at"]),
261
+ created_at=parse_iso(m["created_at"]),
261
262
  )
262
263
  )
263
264
  except Exception: # nosec B110
@@ -375,7 +376,7 @@ class SQLiteCheckpointStore:
375
376
  step=row["step"],
376
377
  node_name=row["node_name"],
377
378
  interrupted=bool(row["interrupted"]),
378
- created_at=datetime.fromisoformat(row["created_at"]),
379
+ created_at=parse_iso(row["created_at"]),
379
380
  )
380
381
  for row in rows
381
382
  ]
@@ -21,7 +21,7 @@ import inspect
21
21
  import json
22
22
  import time
23
23
  import uuid
24
- from dataclasses import dataclass, field
24
+ from dataclasses import dataclass
25
25
  from enum import Enum
26
26
  from typing import (
27
27
  TYPE_CHECKING,
@@ -38,7 +38,7 @@ from typing import (
38
38
 
39
39
  from .._async_utils import run_in_executor_copyctx, run_sync
40
40
  from ..exceptions import GraphExecutionError
41
- from ..stability import beta, stable
41
+ from ..stability import stable
42
42
  from ..trace import AgentTrace, StepType, TraceStep
43
43
  from ..types import AgentResult, Message, Role
44
44
  from ..usage import AgentUsage, UsageStats
@@ -47,7 +47,6 @@ from .node import (
47
47
  ParallelGroupNode,
48
48
  SubgraphNode,
49
49
  build_context_messages,
50
- default_input_transform,
51
50
  default_output_transform,
52
51
  )
53
52
  from .state import (
@@ -64,7 +63,6 @@ from .state import (
64
63
  )
65
64
 
66
65
  if TYPE_CHECKING:
67
- from ..agent.core import Agent
68
66
  from ..cancellation import CancellationToken
69
67
  from ..guardrails.pipeline import GuardrailsPipeline
70
68
  from ..observer import AgentObserver
@@ -835,7 +833,6 @@ class AgentGraph:
835
833
  self._trace_step(trace, StepType.GRAPH_CHECKPOINT, checkpoint_id=ckpt_id)
836
834
 
837
835
  # Resolve next node
838
- prev_node = current
839
836
  current = self._resolve_next_node(current, state, trace, run_id)
840
837
 
841
838
  # Output guardrails
@@ -15,9 +15,7 @@ from ..stability import stable
15
15
  from .state import STATE_KEY_LAST_OUTPUT, ContextMode, GraphState
16
16
 
17
17
  if TYPE_CHECKING:
18
- from ..agent.core import Agent
19
- from ..types import AgentResult, Message
20
- from .graph import ErrorPolicy
18
+ pass
21
19
 
22
20
 
23
21
  @stable
@@ -13,10 +13,10 @@ import copy
13
13
  import json
14
14
  from dataclasses import dataclass, field
15
15
  from enum import Enum
16
- from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple
16
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple
17
17
 
18
18
  if TYPE_CHECKING:
19
- from ..types import AgentResult, Message
19
+ pass
20
20
 
21
21
  from ..stability import register_stability, stable
22
22
 
@@ -141,7 +141,7 @@ class GraphState:
141
141
  @classmethod
142
142
  def from_dict(cls, d: Dict[str, Any]) -> "GraphState":
143
143
  """Reconstruct a GraphState from a dictionary produced by to_dict()."""
144
- from ..types import Message, Role # noqa: F811
144
+ from ..types import Message # noqa: F811
145
145
 
146
146
  messages: List[Any] = []
147
147
  for m in d.get("messages", []):