synapsekit 1.2.0__tar.gz → 1.3.0__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 (306) hide show
  1. {synapsekit-1.2.0 → synapsekit-1.3.0}/.gitignore +1 -0
  2. {synapsekit-1.2.0 → synapsekit-1.3.0}/PKG-INFO +6 -1
  3. {synapsekit-1.2.0 → synapsekit-1.3.0}/pyproject.toml +5 -2
  4. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/__init__.py +44 -1
  5. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/__init__.py +21 -0
  6. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/function_calling.py +91 -0
  7. synapsekit-1.3.0/src/synapsekit/agents/pii_redactor.py +103 -0
  8. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/react.py +69 -0
  9. synapsekit-1.3.0/src/synapsekit/agents/step_events.py +61 -0
  10. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/cli/main.py +23 -0
  11. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/cli/test.py +64 -0
  12. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/evaluation/__init__.py +5 -0
  13. synapsekit-1.3.0/src/synapsekit/evaluation/regression.py +154 -0
  14. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/__init__.py +8 -0
  15. synapsekit-1.3.0/src/synapsekit/llm/cost_router.py +166 -0
  16. synapsekit-1.3.0/src/synapsekit/llm/fallback_chain.py +86 -0
  17. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/loaders/__init__.py +4 -0
  18. synapsekit-1.3.0/src/synapsekit/loaders/audio.py +103 -0
  19. synapsekit-1.3.0/src/synapsekit/loaders/video.py +140 -0
  20. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/observability/__init__.py +3 -0
  21. synapsekit-1.3.0/src/synapsekit/observability/audit_log.py +262 -0
  22. synapsekit-1.3.0/tests/agents/test_pii_redactor.py +79 -0
  23. synapsekit-1.3.0/tests/agents/test_streaming_steps.py +196 -0
  24. synapsekit-1.3.0/tests/loaders/test_audio_video_loaders.py +135 -0
  25. synapsekit-1.3.0/tests/observability/test_audit_log.py +101 -0
  26. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/test_v060_features.py +1 -1
  27. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/test_v065_features.py +1 -1
  28. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/test_v066_features.py +1 -1
  29. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/test_v068_features.py +1 -1
  30. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/test_v069_features.py +1 -1
  31. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/test_v070_features.py +1 -1
  32. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/test_v120_features.py +2 -2
  33. synapsekit-1.3.0/tests/test_v130_eval_regression.py +174 -0
  34. synapsekit-1.3.0/tests/test_v130_routing.py +218 -0
  35. {synapsekit-1.2.0 → synapsekit-1.3.0}/uv.lock +12 -2
  36. {synapsekit-1.2.0 → synapsekit-1.3.0}/.all-contributorsrc +0 -0
  37. {synapsekit-1.2.0 → synapsekit-1.3.0}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
  38. {synapsekit-1.2.0 → synapsekit-1.3.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  39. {synapsekit-1.2.0 → synapsekit-1.3.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  40. {synapsekit-1.2.0 → synapsekit-1.3.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  41. {synapsekit-1.2.0 → synapsekit-1.3.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  42. {synapsekit-1.2.0 → synapsekit-1.3.0}/.github/profile/README.md +0 -0
  43. {synapsekit-1.2.0 → synapsekit-1.3.0}/.github/workflows/ci.yml +0 -0
  44. {synapsekit-1.2.0 → synapsekit-1.3.0}/.github/workflows/publish.yml +0 -0
  45. {synapsekit-1.2.0 → synapsekit-1.3.0}/.github/workflows/welcome.yml +0 -0
  46. {synapsekit-1.2.0 → synapsekit-1.3.0}/.pre-commit-config.yaml +0 -0
  47. {synapsekit-1.2.0 → synapsekit-1.3.0}/CHANGELOG.md +0 -0
  48. {synapsekit-1.2.0 → synapsekit-1.3.0}/CODE_OF_CONDUCT.md +0 -0
  49. {synapsekit-1.2.0 → synapsekit-1.3.0}/CONTRIBUTING.md +0 -0
  50. {synapsekit-1.2.0 → synapsekit-1.3.0}/LICENSE +0 -0
  51. {synapsekit-1.2.0 → synapsekit-1.3.0}/Makefile +0 -0
  52. {synapsekit-1.2.0 → synapsekit-1.3.0}/README.md +0 -0
  53. {synapsekit-1.2.0 → synapsekit-1.3.0}/SECURITY.md +0 -0
  54. {synapsekit-1.2.0 → synapsekit-1.3.0}/assets/banner.svg +0 -0
  55. {synapsekit-1.2.0 → synapsekit-1.3.0}/assets/favicon.svg +0 -0
  56. {synapsekit-1.2.0 → synapsekit-1.3.0}/assets/logo.svg +0 -0
  57. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/_api.py +0 -0
  58. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/_compat.py +0 -0
  59. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/a2a/__init__.py +0 -0
  60. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/a2a/agent_card.py +0 -0
  61. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/a2a/client.py +0 -0
  62. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/a2a/server.py +0 -0
  63. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/a2a/types.py +0 -0
  64. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/base.py +0 -0
  65. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/executor.py +0 -0
  66. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/guardrails.py +0 -0
  67. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/memory.py +0 -0
  68. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/multi/__init__.py +0 -0
  69. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/multi/crew.py +0 -0
  70. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/multi/handoff.py +0 -0
  71. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/multi/supervisor.py +0 -0
  72. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/registry.py +0 -0
  73. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tool_decorator.py +0 -0
  74. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/__init__.py +0 -0
  75. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/arxiv_search.py +0 -0
  76. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/brave_search.py +0 -0
  77. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/calculator.py +0 -0
  78. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/datetime_tool.py +0 -0
  79. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/duck_search.py +0 -0
  80. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/email_tool.py +0 -0
  81. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/file_list.py +0 -0
  82. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/file_read.py +0 -0
  83. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/file_write.py +0 -0
  84. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/github_api.py +0 -0
  85. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/graphql.py +0 -0
  86. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/http_request.py +0 -0
  87. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/human_input.py +0 -0
  88. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/jira.py +0 -0
  89. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/json_query.py +0 -0
  90. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/pdf_reader.py +0 -0
  91. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/pubmed_search.py +0 -0
  92. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/python_repl.py +0 -0
  93. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/regex_tool.py +0 -0
  94. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/sentiment.py +0 -0
  95. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/shell.py +0 -0
  96. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/slack.py +0 -0
  97. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/sql_query.py +0 -0
  98. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/sql_schema.py +0 -0
  99. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/summarization.py +0 -0
  100. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/tavily_search.py +0 -0
  101. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/translation.py +0 -0
  102. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/vector_search.py +0 -0
  103. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/web_scraper.py +0 -0
  104. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/web_search.py +0 -0
  105. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/wikipedia.py +0 -0
  106. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/agents/tools/youtube_search.py +0 -0
  107. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/cli/__init__.py +0 -0
  108. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/cli/serve.py +0 -0
  109. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/embeddings/__init__.py +0 -0
  110. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/embeddings/backend.py +0 -0
  111. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/evaluation/base.py +0 -0
  112. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/evaluation/decorators.py +0 -0
  113. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/evaluation/faithfulness.py +0 -0
  114. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/evaluation/groundedness.py +0 -0
  115. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/evaluation/pipeline.py +0 -0
  116. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/evaluation/relevancy.py +0 -0
  117. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/__init__.py +0 -0
  118. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/approval.py +0 -0
  119. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/checkpointers/__init__.py +0 -0
  120. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/checkpointers/base.py +0 -0
  121. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/checkpointers/json_file.py +0 -0
  122. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/checkpointers/memory.py +0 -0
  123. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/checkpointers/postgres.py +0 -0
  124. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/checkpointers/redis.py +0 -0
  125. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/checkpointers/sqlite.py +0 -0
  126. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/compiled.py +0 -0
  127. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/dynamic_route.py +0 -0
  128. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/edge.py +0 -0
  129. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/errors.py +0 -0
  130. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/fan_out.py +0 -0
  131. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/graph.py +0 -0
  132. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/interrupt.py +0 -0
  133. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/mermaid.py +0 -0
  134. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/node.py +0 -0
  135. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/state.py +0 -0
  136. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/streaming.py +0 -0
  137. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/subgraph.py +0 -0
  138. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/trace.py +0 -0
  139. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/graph/visualization.py +0 -0
  140. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/_cache.py +0 -0
  141. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/_filesystem_cache.py +0 -0
  142. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/_rate_limit.py +0 -0
  143. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/_redis_cache.py +0 -0
  144. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/_retry.py +0 -0
  145. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/_semantic_cache.py +0 -0
  146. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/_sqlite_cache.py +0 -0
  147. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/anthropic.py +0 -0
  148. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/azure_openai.py +0 -0
  149. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/base.py +0 -0
  150. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/bedrock.py +0 -0
  151. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/cerebras.py +0 -0
  152. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/cohere.py +0 -0
  153. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/deepseek.py +0 -0
  154. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/fireworks.py +0 -0
  155. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/gemini.py +0 -0
  156. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/groq.py +0 -0
  157. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/mistral.py +0 -0
  158. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/multimodal.py +0 -0
  159. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/ollama.py +0 -0
  160. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/openai.py +0 -0
  161. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/openrouter.py +0 -0
  162. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/perplexity.py +0 -0
  163. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/structured.py +0 -0
  164. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/together.py +0 -0
  165. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/llm/vertex_ai.py +0 -0
  166. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/loaders/base.py +0 -0
  167. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/loaders/csv.py +0 -0
  168. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/loaders/directory.py +0 -0
  169. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/loaders/docx.py +0 -0
  170. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/loaders/excel.py +0 -0
  171. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/loaders/html.py +0 -0
  172. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/loaders/image.py +0 -0
  173. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/loaders/json_loader.py +0 -0
  174. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/loaders/markdown.py +0 -0
  175. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/loaders/pdf.py +0 -0
  176. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/loaders/pptx.py +0 -0
  177. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/loaders/text.py +0 -0
  178. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/loaders/web.py +0 -0
  179. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/mcp/__init__.py +0 -0
  180. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/mcp/client.py +0 -0
  181. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/mcp/server.py +0 -0
  182. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/memory/__init__.py +0 -0
  183. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/memory/buffer.py +0 -0
  184. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/memory/conversation.py +0 -0
  185. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/memory/entity.py +0 -0
  186. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/memory/hybrid.py +0 -0
  187. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/memory/redis.py +0 -0
  188. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/memory/sqlite.py +0 -0
  189. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/memory/summary_buffer.py +0 -0
  190. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/memory/token_buffer.py +0 -0
  191. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/observability/budget_guard.py +0 -0
  192. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/observability/cost_tracker.py +0 -0
  193. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/observability/distributed.py +0 -0
  194. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/observability/otel.py +0 -0
  195. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/observability/tracer.py +0 -0
  196. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/observability/ui.py +0 -0
  197. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/parsers/__init__.py +0 -0
  198. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/parsers/json_parser.py +0 -0
  199. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/parsers/list_parser.py +0 -0
  200. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/parsers/pydantic_parser.py +0 -0
  201. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/plugins.py +0 -0
  202. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/prompts/__init__.py +0 -0
  203. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/prompts/hub.py +0 -0
  204. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/prompts/template.py +0 -0
  205. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/py.typed +0 -0
  206. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/rag/__init__.py +0 -0
  207. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/rag/facade.py +0 -0
  208. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/rag/pipeline.py +0 -0
  209. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/__init__.py +0 -0
  210. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/adaptive.py +0 -0
  211. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/base.py +0 -0
  212. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/chroma.py +0 -0
  213. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/cohere_reranker.py +0 -0
  214. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/contextual.py +0 -0
  215. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/contextual_compression.py +0 -0
  216. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/crag.py +0 -0
  217. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/cross_encoder.py +0 -0
  218. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/ensemble.py +0 -0
  219. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/faiss.py +0 -0
  220. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/flare.py +0 -0
  221. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/graphrag.py +0 -0
  222. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/hybrid_search.py +0 -0
  223. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/hyde.py +0 -0
  224. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/multi_step.py +0 -0
  225. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/parent_document.py +0 -0
  226. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/pinecone.py +0 -0
  227. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/qdrant.py +0 -0
  228. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/query_decomposition.py +0 -0
  229. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/rag_fusion.py +0 -0
  230. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/retriever.py +0 -0
  231. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/self_query.py +0 -0
  232. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/self_rag.py +0 -0
  233. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/sentence_window.py +0 -0
  234. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/step_back.py +0 -0
  235. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/retrieval/vectorstore.py +0 -0
  236. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/text_splitters/__init__.py +0 -0
  237. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/text_splitters/base.py +0 -0
  238. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/text_splitters/character.py +0 -0
  239. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/text_splitters/markdown.py +0 -0
  240. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/text_splitters/recursive.py +0 -0
  241. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/text_splitters/semantic.py +0 -0
  242. {synapsekit-1.2.0 → synapsekit-1.3.0}/src/synapsekit/text_splitters/token.py +0 -0
  243. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/__init__.py +0 -0
  244. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/agents/__init__.py +0 -0
  245. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/agents/test_executor.py +0 -0
  246. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/agents/test_function_calling.py +0 -0
  247. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/agents/test_memory.py +0 -0
  248. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/agents/test_react.py +0 -0
  249. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/agents/test_shell_tool.py +0 -0
  250. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/agents/test_sql_schema.py +0 -0
  251. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/agents/test_tool_decorator.py +0 -0
  252. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/agents/test_tools.py +0 -0
  253. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/agents/test_web_scraper.py +0 -0
  254. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/conftest.py +0 -0
  255. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/graph/__init__.py +0 -0
  256. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/graph/test_build.py +0 -0
  257. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/graph/test_checkpointing.py +0 -0
  258. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/graph/test_cycles.py +0 -0
  259. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/graph/test_json_checkpointer.py +0 -0
  260. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/graph/test_mermaid.py +0 -0
  261. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/graph/test_run.py +0 -0
  262. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/graph/test_state.py +0 -0
  263. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/graph/test_stream.py +0 -0
  264. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/graph/test_visualization.py +0 -0
  265. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/llm/__init__.py +0 -0
  266. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/llm/test_cache_retry.py +0 -0
  267. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/llm/test_filesystem_cache.py +0 -0
  268. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/llm/test_function_calling_providers.py +0 -0
  269. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/llm/test_llm.py +0 -0
  270. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/llm/test_providers.py +0 -0
  271. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/llm/test_vertex_ai.py +0 -0
  272. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/loaders/__init__.py +0 -0
  273. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/loaders/test_docx_loader.py +0 -0
  274. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/loaders/test_loaders.py +0 -0
  275. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/loaders/test_markdown_loader.py +0 -0
  276. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/memory/__init__.py +0 -0
  277. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/memory/test_memory.py +0 -0
  278. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/memory/test_redis_memory.py +0 -0
  279. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/observability/__init__.py +0 -0
  280. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/observability/test_tracer.py +0 -0
  281. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/parsers/__init__.py +0 -0
  282. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/parsers/test_parsers.py +0 -0
  283. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/prompts/__init__.py +0 -0
  284. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/prompts/test_prompts.py +0 -0
  285. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/rag/__init__.py +0 -0
  286. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/rag/test_facade.py +0 -0
  287. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/rag/test_pipeline.py +0 -0
  288. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/retrieval/__init__.py +0 -0
  289. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/retrieval/test_backends.py +0 -0
  290. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/retrieval/test_graphrag.py +0 -0
  291. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/retrieval/test_hyde.py +0 -0
  292. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/retrieval/test_retriever.py +0 -0
  293. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/retrieval/test_vectorstore.py +0 -0
  294. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/test_v051_features.py +0 -0
  295. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/test_v052_features.py +0 -0
  296. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/test_v053_features.py +0 -0
  297. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/test_v061_features.py +0 -0
  298. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/test_v062_features.py +0 -0
  299. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/test_v063_features.py +0 -0
  300. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/test_v080_features.py +0 -0
  301. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/test_v090_features.py +0 -0
  302. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/test_v100_features.py +0 -0
  303. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/test_v120_integration.py +0 -0
  304. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/text_splitters/__init__.py +0 -0
  305. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/text_splitters/test_markdown.py +0 -0
  306. {synapsekit-1.2.0 → synapsekit-1.3.0}/tests/text_splitters/test_splitters.py +0 -0
@@ -70,3 +70,4 @@ docs/
70
70
  # Saved vectorstores
71
71
  *.npz
72
72
  typescript
73
+ .synapsekit_evals/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: synapsekit
3
- Version: 1.2.0
3
+ Version: 1.3.0
4
4
  Summary: Async-native Python framework for building production-grade LLM applications. Streaming-first, 2 dependencies, fully transparent.
5
5
  Project-URL: Homepage, https://github.com/SynapseKit/SynapseKit
6
6
  Project-URL: Repository, https://github.com/SynapseKit/SynapseKit
@@ -32,6 +32,7 @@ Requires-Dist: faiss-cpu>=1.7; extra == 'all'
32
32
  Requires-Dist: fastapi>=0.110; extra == 'all'
33
33
  Requires-Dist: google-cloud-aiplatform>=1.38; extra == 'all'
34
34
  Requires-Dist: google-generativeai>=0.7; extra == 'all'
35
+ Requires-Dist: groq>=0.9; extra == 'all'
35
36
  Requires-Dist: httpx>=0.27; extra == 'all'
36
37
  Requires-Dist: lxml>=5.0; extra == 'all'
37
38
  Requires-Dist: mcp>=1.0; extra == 'all'
@@ -49,6 +50,8 @@ Requires-Dist: uvicorn[standard]>=0.29; extra == 'all'
49
50
  Requires-Dist: youtube-search-python>=1.6; extra == 'all'
50
51
  Provides-Extra: anthropic
51
52
  Requires-Dist: anthropic>=0.25; extra == 'anthropic'
53
+ Provides-Extra: audio
54
+ Requires-Dist: openai>=1.0; extra == 'audio'
52
55
  Provides-Extra: bedrock
53
56
  Requires-Dist: boto3>=1.34; extra == 'bedrock'
54
57
  Provides-Extra: chroma
@@ -101,6 +104,8 @@ Provides-Extra: tavily
101
104
  Requires-Dist: tavily-python>=0.3; extra == 'tavily'
102
105
  Provides-Extra: vertex
103
106
  Requires-Dist: google-cloud-aiplatform>=1.38; extra == 'vertex'
107
+ Provides-Extra: video
108
+ Requires-Dist: openai>=1.0; extra == 'video'
104
109
  Provides-Extra: web
105
110
  Requires-Dist: beautifulsoup4>=4.12; extra == 'web'
106
111
  Requires-Dist: httpx>=0.27; extra == 'web'
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "synapsekit"
7
- version = "1.2.0"
7
+ version = "1.3.0"
8
8
  description = "Async-native Python framework for building production-grade LLM applications. Streaming-first, 2 dependencies, fully transparent."
9
9
  authors = [{ name = "Amit", email = "de.amit.nautiyal@gmail.com" }]
10
10
  license = { text = "Apache-2.0" }
@@ -53,6 +53,8 @@ mistral = ["mistralai>=1.0"]
53
53
  gemini = ["google-generativeai>=0.7"]
54
54
  bedrock = ["boto3>=1.34"]
55
55
  groq = ["groq>=0.9"]
56
+ audio = ["openai>=1.0"]
57
+ video = ["openai>=1.0"]
56
58
  excel = ["openpyxl>=3.1"]
57
59
  pptx = ["python-pptx>=0.6"]
58
60
  docx = ["python-docx>=1.0"]
@@ -91,6 +93,7 @@ all = [
91
93
  "fastapi>=0.110",
92
94
  "uvicorn[standard]>=0.29",
93
95
  "psycopg[binary]>=3.1",
96
+ "groq>=0.9",
94
97
  ]
95
98
 
96
99
  [dependency-groups]
@@ -197,6 +200,6 @@ youtube-search-python = "youtubesearchpython"
197
200
  google-cloud-aiplatform = "vertexai"
198
201
 
199
202
  [tool.deptry.per_rule_ignores]
200
- DEP001 = ["sqlalchemy", "pydantic", "aiohttp", "opentelemetry"]
203
+ DEP001 = ["sqlalchemy", "pydantic", "aiohttp", "opentelemetry", "whisper"]
201
204
  DEP002 = ["numpy", "rank-bm25", "beautifulsoup4", "lxml", "faiss-cpu", "google-generativeai", "tavily-python", "youtube-search-python", "psycopg"]
202
205
  DEP004 = ["pydantic"]
@@ -17,6 +17,7 @@ from __future__ import annotations
17
17
  from ._api import deprecated, experimental, public_api
18
18
  from .a2a import A2AClient, A2AMessage, A2AServer, A2ATask, AgentCard, TaskState
19
19
  from .agents import (
20
+ ActionEvent,
20
21
  AgentConfig,
21
22
  AgentExecutor,
22
23
  AgentMemory,
@@ -32,9 +33,11 @@ from .agents import (
32
33
  DateTimeTool,
33
34
  DuckDuckGoSearchTool,
34
35
  EmailTool,
36
+ ErrorEvent,
35
37
  FileListTool,
36
38
  FileReadTool,
37
39
  FileWriteTool,
40
+ FinalAnswerEvent,
38
41
  FunctionCallingAgent,
39
42
  GitHubAPITool,
40
43
  GraphQLTool,
@@ -47,21 +50,27 @@ from .agents import (
47
50
  HumanInputTool,
48
51
  JiraTool,
49
52
  JSONQueryTool,
53
+ ObservationEvent,
50
54
  PDFReaderTool,
51
55
  PIIDetector,
56
+ PIIRedactor,
52
57
  PubMedSearchTool,
53
58
  PythonREPLTool,
54
59
  ReActAgent,
60
+ RedactionResult,
55
61
  RegexTool,
56
62
  SentimentAnalysisTool,
57
63
  ShellTool,
58
64
  SlackTool,
59
65
  SQLQueryTool,
60
66
  SQLSchemaInspectionTool,
67
+ StepEvent,
61
68
  SummarizationTool,
62
69
  SupervisorAgent,
63
70
  Task,
64
71
  TavilySearchTool,
72
+ ThoughtEvent,
73
+ TokenEvent,
65
74
  ToolRegistry,
66
75
  ToolResult,
67
76
  TopicRestrictor,
@@ -77,11 +86,15 @@ from .agents import (
77
86
  from .embeddings.backend import SynapsekitEmbeddings
78
87
  from .evaluation import (
79
88
  EvalCaseMeta,
89
+ EvalRegression,
90
+ EvalSnapshot,
80
91
  EvaluationPipeline,
81
92
  EvaluationResult,
82
93
  FaithfulnessMetric,
83
94
  GroundednessMetric,
95
+ MetricDelta,
84
96
  MetricResult,
97
+ RegressionReport,
85
98
  RelevancyMetric,
86
99
  eval_case,
87
100
  )
@@ -122,6 +135,8 @@ from .graph import (
122
135
  ws_stream,
123
136
  )
124
137
  from .llm.base import BaseLLM, LLMConfig
138
+ from .llm.cost_router import QUALITY_TABLE, CostRouter, CostRouterConfig, RouterModelSpec
139
+ from .llm.fallback_chain import FallbackChain, FallbackChainConfig
125
140
  from .llm.multimodal import AudioContent, ImageContent, MultimodalMessage
126
141
  from .llm.structured import generate_structured
127
142
  from .loaders.base import Document
@@ -144,6 +159,8 @@ from .memory.sqlite import SQLiteConversationMemory
144
159
  from .memory.summary_buffer import SummaryBufferMemory
145
160
  from .memory.token_buffer import TokenBufferMemory
146
161
  from .observability import (
162
+ AuditEntry,
163
+ AuditLog,
147
164
  BudgetExceededError,
148
165
  BudgetGuard,
149
166
  BudgetLimit,
@@ -197,7 +214,7 @@ from .text_splitters import (
197
214
  TokenAwareSplitter,
198
215
  )
199
216
 
200
- __version__ = "1.2.0"
217
+ __version__ = "1.3.0"
201
218
  __all__ = [
202
219
  # Facade
203
220
  "RAG",
@@ -207,6 +224,12 @@ __all__ = [
207
224
  # LLM
208
225
  "BaseLLM",
209
226
  "LLMConfig",
227
+ "CostRouter",
228
+ "CostRouterConfig",
229
+ "RouterModelSpec",
230
+ "QUALITY_TABLE",
231
+ "FallbackChain",
232
+ "FallbackChainConfig",
210
233
  "AzureOpenAILLM",
211
234
  "CerebrasLLM",
212
235
  "DeepSeekLLM",
@@ -395,14 +418,20 @@ __all__ = [
395
418
  "generate_structured",
396
419
  # Evaluation
397
420
  "EvalCaseMeta",
421
+ "EvalRegression",
422
+ "EvalSnapshot",
398
423
  "EvaluationPipeline",
399
424
  "EvaluationResult",
400
425
  "FaithfulnessMetric",
401
426
  "GroundednessMetric",
427
+ "MetricDelta",
402
428
  "MetricResult",
429
+ "RegressionReport",
403
430
  "RelevancyMetric",
404
431
  "eval_case",
405
432
  # Observability
433
+ "AuditEntry",
434
+ "AuditLog",
406
435
  "DistributedTracer",
407
436
  "OTelExporter",
408
437
  "Span",
@@ -421,11 +450,23 @@ __all__ = [
421
450
  "Guardrails",
422
451
  "GuardrailResult",
423
452
  "PIIDetector",
453
+ "PIIRedactor",
454
+ "RedactionResult",
424
455
  "TopicRestrictor",
456
+ # Step events
457
+ "ActionEvent",
458
+ "ErrorEvent",
459
+ "FinalAnswerEvent",
460
+ "ObservationEvent",
461
+ "StepEvent",
462
+ "ThoughtEvent",
463
+ "TokenEvent",
425
464
  # Multimodal
426
465
  "AudioContent",
427
466
  "ImageContent",
428
467
  "MultimodalMessage",
468
+ "AudioLoader",
469
+ "VideoLoader",
429
470
  "ImageLoader",
430
471
  # Plugins
431
472
  "PluginRegistry",
@@ -456,6 +497,8 @@ _LAZY_IMPORTS = {
456
497
  "RedisCheckpointer": "graph.checkpointers.redis",
457
498
  "PostgresCheckpointer": "graph.checkpointers.postgres",
458
499
  # Loaders
500
+ "AudioLoader": "loaders.audio",
501
+ "VideoLoader": "loaders.video",
459
502
  "DocxLoader": "loaders.docx",
460
503
  "ExcelLoader": "loaders.excel",
461
504
  "PowerPointLoader": "loaders.pptx",
@@ -20,8 +20,18 @@ from .multi import (
20
20
  Task,
21
21
  WorkerAgent,
22
22
  )
23
+ from .pii_redactor import PIIRedactor, RedactionResult
23
24
  from .react import ReActAgent
24
25
  from .registry import ToolRegistry
26
+ from .step_events import (
27
+ ActionEvent,
28
+ ErrorEvent,
29
+ FinalAnswerEvent,
30
+ ObservationEvent,
31
+ StepEvent,
32
+ ThoughtEvent,
33
+ TokenEvent,
34
+ )
25
35
  from .tool_decorator import tool
26
36
  from .tools import (
27
37
  ArxivSearchTool,
@@ -111,6 +121,17 @@ __all__ = [
111
121
  "WebSearchTool",
112
122
  "WikipediaTool",
113
123
  "YouTubeSearchTool",
124
+ # PIIRedactor
125
+ "PIIRedactor",
126
+ "RedactionResult",
127
+ # Step events
128
+ "ActionEvent",
129
+ "ErrorEvent",
130
+ "FinalAnswerEvent",
131
+ "ObservationEvent",
132
+ "StepEvent",
133
+ "ThoughtEvent",
134
+ "TokenEvent",
114
135
  # Multi-agent
115
136
  "Crew",
116
137
  "CrewAgent",
@@ -125,6 +125,97 @@ class FunctionCallingAgent:
125
125
  for word in answer.split(" "):
126
126
  yield word + " "
127
127
 
128
+ async def stream_steps(self, query: str) -> AsyncGenerator:
129
+ """Stream step-by-step events for function-calling agent.
130
+
131
+ Yields ``StepEvent`` instances (``ActionEvent``, ``ObservationEvent``,
132
+ ``TokenEvent``, ``FinalAnswerEvent``, ``ErrorEvent``).
133
+ """
134
+ from .step_events import (
135
+ ActionEvent,
136
+ ErrorEvent,
137
+ FinalAnswerEvent,
138
+ ObservationEvent,
139
+ TokenEvent,
140
+ )
141
+
142
+ self._check_support()
143
+ self._memory.clear()
144
+
145
+ messages: list[dict] = [
146
+ {"role": "system", "content": self._system_prompt},
147
+ {"role": "user", "content": query},
148
+ ]
149
+
150
+ tool_schemas = self._registry.schemas()
151
+
152
+ for _ in range(self._max_iterations):
153
+ result: dict[str, Any] = await self._llm.call_with_tools(messages, tool_schemas)
154
+
155
+ tool_calls = result.get("tool_calls")
156
+ content = result.get("content")
157
+
158
+ # No tool calls → final answer
159
+ if not tool_calls:
160
+ answer = content or ""
161
+ for token in answer.split(" "):
162
+ yield TokenEvent(token=token + " ")
163
+ yield FinalAnswerEvent(answer=answer)
164
+ return
165
+
166
+ # Append assistant message with tool_calls
167
+ messages.append(
168
+ {
169
+ "role": "assistant",
170
+ "content": None,
171
+ "tool_calls": [
172
+ {
173
+ "id": tc["id"],
174
+ "type": "function",
175
+ "function": {
176
+ "name": tc["name"],
177
+ "arguments": json.dumps(tc["arguments"]),
178
+ },
179
+ }
180
+ for tc in tool_calls
181
+ ],
182
+ }
183
+ )
184
+
185
+ # Execute each tool
186
+ for tc in tool_calls:
187
+ yield ActionEvent(tool=tc["name"], tool_input=tc["arguments"])
188
+
189
+ try:
190
+ tool = self._registry.get(tc["name"])
191
+ tool_result = await tool.run(**tc["arguments"])
192
+ observation = str(tool_result)
193
+ except Exception as e:
194
+ observation = f"Error: {e}"
195
+ yield ErrorEvent(error=str(e))
196
+
197
+ messages.append(
198
+ {
199
+ "role": "tool",
200
+ "tool_call_id": tc["id"],
201
+ "content": observation,
202
+ }
203
+ )
204
+ yield ObservationEvent(observation=observation, tool=tc["name"])
205
+
206
+ self._memory.add_step(
207
+ AgentStep(
208
+ thought="",
209
+ action=tc["name"],
210
+ action_input=json.dumps(tc["arguments"]),
211
+ observation=observation,
212
+ )
213
+ )
214
+
215
+ yield FinalAnswerEvent(
216
+ answer="I was unable to complete the task within the allowed number of steps."
217
+ )
218
+
128
219
  @property
129
220
  def memory(self) -> AgentMemory:
130
221
  return self._memory
@@ -0,0 +1,103 @@
1
+ """PIIRedactor — redact and optionally restore PII in text."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+ from dataclasses import dataclass, field
7
+
8
+ from ..llm.base import BaseLLM
9
+ from .guardrails import PIIDetector
10
+
11
+
12
+ @dataclass
13
+ class RedactionResult:
14
+ """Result of a PII redaction operation."""
15
+
16
+ redacted_text: str
17
+ mapping: dict[str, str] = field(default_factory=dict)
18
+ pii_types_found: list[str] = field(default_factory=list)
19
+
20
+
21
+ class PIIRedactor:
22
+ """Redact PII from text using the existing ``PIIDetector`` patterns.
23
+
24
+ Supports two modes:
25
+
26
+ - ``"mask"`` (default) — reversible; replaces PII with placeholders like
27
+ ``[EMAIL_1]`` and stores a mapping so originals can be restored.
28
+ - ``"redact"`` — irreversible; same placeholders but no restore.
29
+
30
+ Same-value deduplication: identical PII values always receive the same
31
+ placeholder within a single ``redact()`` call.
32
+
33
+ Example::
34
+
35
+ redactor = PIIRedactor(pii_types=["email", "phone"])
36
+ result = redactor.redact("Email me at a@b.com or a@b.com, call 555-123-4567")
37
+ # result.redacted_text -> "Email me at [EMAIL_1] or [EMAIL_1], call [PHONE_1]"
38
+ original = redactor.restore(result.redacted_text, result.mapping)
39
+ """
40
+
41
+ def __init__(
42
+ self,
43
+ pii_types: list[str] | None = None,
44
+ mode: str = "mask",
45
+ ) -> None:
46
+ if mode not in ("mask", "redact"):
47
+ raise ValueError(f"mode must be 'mask' or 'redact', got {mode!r}")
48
+ self._mode = mode
49
+ self._pii_types = pii_types or list(PIIDetector._PATTERNS.keys())
50
+ self._compiled: dict[str, re.Pattern[str]] = {
51
+ name: re.compile(pattern)
52
+ for name, pattern in PIIDetector._PATTERNS.items()
53
+ if name in self._pii_types
54
+ }
55
+
56
+ def redact(self, text: str) -> RedactionResult:
57
+ """Replace PII with numbered placeholders."""
58
+ mapping: dict[str, str] = {} # placeholder -> original
59
+ value_to_placeholder: dict[str, str] = {} # original -> placeholder
60
+ counters: dict[str, int] = {}
61
+ pii_types_found: set[str] = set()
62
+ redacted = text
63
+
64
+ for pii_type, pattern in self._compiled.items():
65
+ matches = pattern.findall(redacted)
66
+ if not matches:
67
+ continue
68
+ pii_types_found.add(pii_type)
69
+ for match in matches:
70
+ if match in value_to_placeholder:
71
+ continue
72
+ tag = pii_type.upper()
73
+ counters.setdefault(pii_type, 0)
74
+ counters[pii_type] += 1
75
+ placeholder = f"[{tag}_{counters[pii_type]}]"
76
+ value_to_placeholder[match] = placeholder
77
+ mapping[placeholder] = match
78
+
79
+ # Apply replacements (longest values first to avoid partial matches)
80
+ for value in sorted(value_to_placeholder, key=len, reverse=True):
81
+ redacted = redacted.replace(value, value_to_placeholder[value])
82
+
83
+ return RedactionResult(
84
+ redacted_text=redacted,
85
+ mapping=mapping if self._mode == "mask" else {},
86
+ pii_types_found=sorted(pii_types_found),
87
+ )
88
+
89
+ def restore(self, text: str, mapping: dict[str, str]) -> str:
90
+ """Re-inject original PII values. No-op in ``'redact'`` mode."""
91
+ if self._mode == "redact" or not mapping:
92
+ return text
93
+ result = text
94
+ for placeholder, original in mapping.items():
95
+ result = result.replace(placeholder, original)
96
+ return result
97
+
98
+ async def wrap_generate(self, llm: BaseLLM, prompt: str) -> tuple[str, RedactionResult]:
99
+ """Convenience: redact prompt, generate, restore response."""
100
+ redaction = self.redact(prompt)
101
+ response = await llm.generate(redaction.redacted_text)
102
+ restored = self.restore(response, redaction.mapping)
103
+ return restored, redaction
@@ -149,6 +149,75 @@ class ReActAgent:
149
149
  for word in answer.split(" "):
150
150
  yield word + " "
151
151
 
152
+ async def stream_steps(self, query: str) -> AsyncGenerator:
153
+ """Stream step-by-step events including thoughts, actions, and tokens.
154
+
155
+ Yields ``StepEvent`` instances (``ThoughtEvent``, ``ActionEvent``,
156
+ ``ObservationEvent``, ``TokenEvent``, ``FinalAnswerEvent``, ``ErrorEvent``).
157
+ """
158
+ from .step_events import (
159
+ ActionEvent,
160
+ ErrorEvent,
161
+ FinalAnswerEvent,
162
+ ObservationEvent,
163
+ ThoughtEvent,
164
+ TokenEvent,
165
+ )
166
+
167
+ self._memory.clear()
168
+
169
+ for _ in range(self._max_iterations):
170
+ messages = self._build_messages(query)
171
+
172
+ # Stream tokens live
173
+ full_response = ""
174
+ async for token in self._llm.stream_with_messages(messages):
175
+ yield TokenEvent(token=token)
176
+ full_response += token
177
+
178
+ # Check for final answer
179
+ final = _parse_final_answer(full_response)
180
+ if final is not None:
181
+ yield FinalAnswerEvent(answer=final)
182
+ return
183
+
184
+ # Parse action
185
+ action_name, action_input = _parse_action(full_response)
186
+ thought = _parse_thought(full_response)
187
+
188
+ if thought:
189
+ yield ThoughtEvent(thought=thought)
190
+
191
+ if not action_name:
192
+ yield FinalAnswerEvent(answer=full_response.strip())
193
+ return
194
+
195
+ yield ActionEvent(tool=action_name, tool_input=action_input)
196
+
197
+ # Execute tool
198
+ try:
199
+ tool = self._registry.get(action_name)
200
+ result = await tool.run(input=action_input)
201
+ observation = str(result)
202
+ except Exception as e:
203
+ observation = f"Error: {e}"
204
+ yield ErrorEvent(error=str(e))
205
+
206
+ yield ObservationEvent(observation=observation, tool=action_name)
207
+
208
+ self._memory.add_step(
209
+ AgentStep(
210
+ thought=thought,
211
+ action=action_name,
212
+ action_input=action_input,
213
+ observation=observation,
214
+ )
215
+ )
216
+
217
+ yield FinalAnswerEvent(
218
+ answer="I was unable to find the answer within the allowed number of steps."
219
+ )
220
+
152
221
  @property
153
222
  def memory(self) -> AgentMemory:
154
223
  return self._memory
@@ -0,0 +1,61 @@
1
+ """Step event types for streaming agent reasoning."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from typing import Any
7
+
8
+
9
+ @dataclass
10
+ class ThoughtEvent:
11
+ """Agent's internal reasoning step."""
12
+
13
+ thought: str
14
+ type: str = "thought"
15
+
16
+
17
+ @dataclass
18
+ class ActionEvent:
19
+ """Agent decided to call a tool."""
20
+
21
+ tool: str
22
+ tool_input: str | dict[str, Any] = ""
23
+ type: str = "action"
24
+
25
+
26
+ @dataclass
27
+ class ObservationEvent:
28
+ """Result from a tool execution."""
29
+
30
+ observation: str
31
+ tool: str = ""
32
+ type: str = "observation"
33
+
34
+
35
+ @dataclass
36
+ class TokenEvent:
37
+ """A single streamed token from the LLM."""
38
+
39
+ token: str
40
+ type: str = "token"
41
+
42
+
43
+ @dataclass
44
+ class FinalAnswerEvent:
45
+ """The agent's final answer."""
46
+
47
+ answer: str
48
+ type: str = "final_answer"
49
+
50
+
51
+ @dataclass
52
+ class ErrorEvent:
53
+ """An error occurred during agent execution."""
54
+
55
+ error: str
56
+ type: str = "error"
57
+
58
+
59
+ StepEvent = (
60
+ ThoughtEvent | ActionEvent | ObservationEvent | TokenEvent | FinalAnswerEvent | ErrorEvent
61
+ )
@@ -27,6 +27,29 @@ def _add_test_parser(subparsers: argparse._SubParsersAction) -> None: # type: i
27
27
  default="table",
28
28
  help="Output format (default: table)",
29
29
  )
30
+ p.add_argument(
31
+ "--save",
32
+ dest="save_snapshot",
33
+ metavar="NAME",
34
+ help="Save results as a named snapshot",
35
+ )
36
+ p.add_argument(
37
+ "--compare",
38
+ dest="compare_baseline",
39
+ metavar="BASELINE",
40
+ help="Compare results against a saved baseline snapshot",
41
+ )
42
+ p.add_argument(
43
+ "--fail-on-regression",
44
+ action="store_true",
45
+ default=False,
46
+ help="Exit with code 1 if regressions are detected",
47
+ )
48
+ p.add_argument(
49
+ "--snapshot-dir",
50
+ default=".synapsekit_evals",
51
+ help="Snapshot storage directory (default: .synapsekit_evals)",
52
+ )
30
53
 
31
54
 
32
55
  def main(argv: list[str] | None = None) -> None: