reactifact 0.14.2__tar.gz → 0.15.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 (315) hide show
  1. {reactifact-0.14.2/reactifact.egg-info → reactifact-0.15.0}/PKG-INFO +2 -2
  2. {reactifact-0.14.2 → reactifact-0.15.0}/README.md +1 -1
  3. {reactifact-0.14.2 → reactifact-0.15.0}/pyproject.toml +1 -1
  4. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/__init__.py +1 -1
  5. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/web.py +19 -4
  6. {reactifact-0.14.2 → reactifact-0.15.0/reactifact.egg-info}/PKG-INFO +2 -2
  7. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_chat_web.py +72 -0
  8. {reactifact-0.14.2 → reactifact-0.15.0}/LICENSE +0 -0
  9. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/__main__.py +0 -0
  10. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/_extras.py +0 -0
  11. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/_httpx.py +0 -0
  12. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/a2a/__init__.py +0 -0
  13. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/a2a/client.py +0 -0
  14. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/a2a/models.py +0 -0
  15. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/a2a/remote.py +0 -0
  16. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/a2a/server.py +0 -0
  17. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/agent_tool.py +0 -0
  18. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/agents.py +0 -0
  19. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/artifacts.py +0 -0
  20. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/audit.py +0 -0
  21. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/authz.py +0 -0
  22. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/branching.py +0 -0
  23. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/budget.py +0 -0
  24. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/cache.py +0 -0
  25. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/chat.py +0 -0
  26. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/checkpoints.py +0 -0
  27. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/cli/__init__.py +0 -0
  28. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/cli/branch.py +0 -0
  29. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/cli/common.py +0 -0
  30. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/cli/context.py +0 -0
  31. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/cli/eval.py +0 -0
  32. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/cli/graph.py +0 -0
  33. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/cli/replay.py +0 -0
  34. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/cli/scenario.py +0 -0
  35. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/cli/skills.py +0 -0
  36. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/cli/trace.py +0 -0
  37. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/commit.py +0 -0
  38. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/commit_log.py +0 -0
  39. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/consume.py +0 -0
  40. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/context.py +0 -0
  41. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/context_builder.py +0 -0
  42. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/effects.py +0 -0
  43. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/eval/__init__.py +0 -0
  44. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/eval/dataset.py +0 -0
  45. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/eval/evaluators.py +0 -0
  46. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/eval/judge.py +0 -0
  47. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/eval/online.py +0 -0
  48. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/eval/runner.py +0 -0
  49. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/eval/scoring.py +0 -0
  50. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/events.py +0 -0
  51. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/guardrails.py +0 -0
  52. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/interrupt.py +0 -0
  53. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/llm_agent.py +0 -0
  54. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/logging.py +0 -0
  55. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/mcp/__init__.py +0 -0
  56. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/mcp/client.py +0 -0
  57. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/mcp/oauth.py +0 -0
  58. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/mcp/server.py +0 -0
  59. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/metrics.py +0 -0
  60. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/native_tool_use.py +0 -0
  61. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/operations.py +0 -0
  62. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/patches.py +0 -0
  63. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/pricing.py +0 -0
  64. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/produce.py +0 -0
  65. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/prompts.py +0 -0
  66. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/__init__.py +0 -0
  67. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/_retry.py +0 -0
  68. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/anthropic.py +0 -0
  69. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/azure.py +0 -0
  70. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/cerebras.py +0 -0
  71. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/chat.py +0 -0
  72. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/contracts.py +0 -0
  73. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/deepseek.py +0 -0
  74. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/fake.py +0 -0
  75. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/fireworks.py +0 -0
  76. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/gemini.py +0 -0
  77. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/github_models.py +0 -0
  78. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/groq.py +0 -0
  79. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/image.py +0 -0
  80. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/mistral.py +0 -0
  81. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/nvidia.py +0 -0
  82. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/ollama.py +0 -0
  83. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/openai.py +0 -0
  84. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/openrouter.py +0 -0
  85. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/perplexity.py +0 -0
  86. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/qwen.py +0 -0
  87. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/speech.py +0 -0
  88. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/together.py +0 -0
  89. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/video.py +0 -0
  90. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/xai.py +0 -0
  91. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/providers/zai.py +0 -0
  92. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/py.typed +0 -0
  93. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/quick/__init__.py +0 -0
  94. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/quick/_shared.py +0 -0
  95. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/quick/agent.py +0 -0
  96. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/quick/chat.py +0 -0
  97. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/quick/models.py +0 -0
  98. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/quick/rag.py +0 -0
  99. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/quick/tools_agent.py +0 -0
  100. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/quota.py +0 -0
  101. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/recipes/__init__.py +0 -0
  102. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/recipes/cleanup.py +0 -0
  103. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/recipes/conversation.py +0 -0
  104. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/recipes/identity.py +0 -0
  105. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/recipes/inputs.py +0 -0
  106. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/recipes/memory.py +0 -0
  107. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/recipes/plan_execute.py +0 -0
  108. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/recipes/reflection.py +0 -0
  109. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/recipes/resolve.py +0 -0
  110. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/recipes/rollback.py +0 -0
  111. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/recipes/search.py +0 -0
  112. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/recipes/skills.py +0 -0
  113. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/recipes/status.py +0 -0
  114. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/recipes/supervisor.py +0 -0
  115. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/recipes/text.py +0 -0
  116. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/recipes/tool_loop.py +0 -0
  117. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/redaction.py +0 -0
  118. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/relations.py +0 -0
  119. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/replay.py +0 -0
  120. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/request.py +0 -0
  121. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/resources.py +0 -0
  122. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/routing.py +0 -0
  123. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/runtime.py +0 -0
  124. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/scheduler.py +0 -0
  125. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/session.py +0 -0
  126. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/skills/reactifact/SKILL.md +0 -0
  127. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/skills/reactifact/references/effects-and-state.md +0 -0
  128. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/skills/reactifact/references/trust-and-safety.md +0 -0
  129. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/skills/reactifact-agents/SKILL.md +0 -0
  130. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/skills/reactifact-agents/references/consume.md +0 -0
  131. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/skills/reactifact-agents/references/effects.md +0 -0
  132. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/skills/reactifact-eval/SKILL.md +0 -0
  133. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/skills/reactifact-eval/references/online.md +0 -0
  134. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/skills/reactifact-from-langchain/SKILL.md +0 -0
  135. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/skills/reactifact-llm/SKILL.md +0 -0
  136. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/skills/reactifact-llm/references/providers.md +0 -0
  137. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/skills/reactifact-llm/references/tools.md +0 -0
  138. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/skills/reactifact-observability/SKILL.md +0 -0
  139. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/skills/reactifact-rag/SKILL.md +0 -0
  140. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/skills/reactifact-rag/references/sources.md +0 -0
  141. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/skills/reactifact-testing/SKILL.md +0 -0
  142. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/sources.py +0 -0
  143. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/streaming.py +0 -0
  144. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/structured.py +0 -0
  145. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/testing/__init__.py +0 -0
  146. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/testing/assertions.py +0 -0
  147. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/testing/exceptions.py +0 -0
  148. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/testing/fault.py +0 -0
  149. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/testing/golden.py +0 -0
  150. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/testing/lab.py +0 -0
  151. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/testing/mock.py +0 -0
  152. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/testing/pytest_plugin.py +0 -0
  153. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/testing/record.py +0 -0
  154. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/testing/registry.py +0 -0
  155. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/tool_use.py +0 -0
  156. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/tools.py +0 -0
  157. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/tracing/__init__.py +0 -0
  158. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/tracing/_otlp.py +0 -0
  159. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/tracing/columns.py +0 -0
  160. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/tracing/langfuse.py +0 -0
  161. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/tracing/models.py +0 -0
  162. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/tracing/otlp.py +0 -0
  163. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/tracing/postgres.py +0 -0
  164. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/tracing/store.py +0 -0
  165. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/tracing/templates/app.css +0 -0
  166. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/tracing/templates/sessions.html +0 -0
  167. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/tracing/templates/ui.html +0 -0
  168. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/tracing/templates/ui_run.html +0 -0
  169. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/tracing/tracer.py +0 -0
  170. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/tracing/web.py +0 -0
  171. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/triggers.py +0 -0
  172. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/types.py +0 -0
  173. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/verify.py +0 -0
  174. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact/viz.py +0 -0
  175. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact.egg-info/SOURCES.txt +0 -0
  176. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact.egg-info/dependency_links.txt +0 -0
  177. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact.egg-info/entry_points.txt +0 -0
  178. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact.egg-info/requires.txt +0 -0
  179. {reactifact-0.14.2 → reactifact-0.15.0}/reactifact.egg-info/top_level.txt +0 -0
  180. {reactifact-0.14.2 → reactifact-0.15.0}/setup.cfg +0 -0
  181. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_a2a.py +0 -0
  182. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_a2a_example.py +0 -0
  183. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_a2a_interop.py +0 -0
  184. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_absent_consume.py +0 -0
  185. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_adaptive.py +0 -0
  186. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_agent_tool.py +0 -0
  187. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_anthropic_provider.py +0 -0
  188. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_artifacts.py +0 -0
  189. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_audit.py +0 -0
  190. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_authz.py +0 -0
  191. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_backbone.py +0 -0
  192. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_branching.py +0 -0
  193. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_budget.py +0 -0
  194. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_cache.py +0 -0
  195. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_canonical_ports.py +0 -0
  196. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_chat_example.py +0 -0
  197. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_chat_memory.py +0 -0
  198. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_chat_outbox.py +0 -0
  199. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_checkpoint.py +0 -0
  200. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_checkpoints_concurrency.py +0 -0
  201. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_cli.py +0 -0
  202. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_cli_scenario.py +0 -0
  203. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_commit_log.py +0 -0
  204. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_compaction.py +0 -0
  205. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_concurrency.py +0 -0
  206. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_consumes_produces.py +0 -0
  207. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_context_builder.py +0 -0
  208. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_correlated_consume.py +0 -0
  209. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_debounce.py +0 -0
  210. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_determinism.py +0 -0
  211. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_devops.py +0 -0
  212. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_devops_online.py +0 -0
  213. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_devops_web.py +0 -0
  214. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_effects.py +0 -0
  215. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_eval.py +0 -0
  216. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_eval_dataset.py +0 -0
  217. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_eval_judge.py +0 -0
  218. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_eval_online.py +0 -0
  219. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_eval_trajectory.py +0 -0
  220. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_fintech_audit.py +0 -0
  221. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_forklab.py +0 -0
  222. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_forklab_web.py +0 -0
  223. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_friendly_api.py +0 -0
  224. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_gemini_provider.py +0 -0
  225. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_golden.py +0 -0
  226. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_guardrails.py +0 -0
  227. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_hitl.py +0 -0
  228. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_image_provider.py +0 -0
  229. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_incident_commander.py +0 -0
  230. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_invalidation.py +0 -0
  231. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_join_consume.py +0 -0
  232. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_knowledge.py +0 -0
  233. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_knowledge_web.py +0 -0
  234. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_llm_ladder.py +0 -0
  235. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_logging.py +0 -0
  236. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_loop_bound_client.py +0 -0
  237. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_mcp.py +0 -0
  238. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_medic_lab.py +0 -0
  239. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_medic_lab_web.py +0 -0
  240. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_metrics.py +0 -0
  241. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_multisource.py +0 -0
  242. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_native_tool_use.py +0 -0
  243. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_openai_provider.py +0 -0
  244. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_outbox.py +0 -0
  245. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_patches.py +0 -0
  246. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_pending_actions.py +0 -0
  247. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_ports.py +0 -0
  248. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_produce_styles.py +0 -0
  249. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_produce_trigger.py +0 -0
  250. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_prompts.py +0 -0
  251. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_provider_auth.py +0 -0
  252. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_provider_retry.py +0 -0
  253. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_providers_integration.py +0 -0
  254. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_public_api.py +0 -0
  255. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_quick.py +0 -0
  256. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_quota.py +0 -0
  257. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_reacts_to.py +0 -0
  258. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_recipe_conversation.py +0 -0
  259. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_recipe_plan_execute.py +0 -0
  260. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_recipe_reflection.py +0 -0
  261. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_recipe_supervisor.py +0 -0
  262. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_recipe_tool_loop.py +0 -0
  263. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_recipes.py +0 -0
  264. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_recipes_inputs.py +0 -0
  265. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_recipes_memory.py +0 -0
  266. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_recipes_skills.py +0 -0
  267. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_redaction.py +0 -0
  268. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_relation_graph.py +0 -0
  269. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_relations.py +0 -0
  270. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_repair.py +0 -0
  271. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_repair_web.py +0 -0
  272. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_replay.py +0 -0
  273. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_repo_agent.py +0 -0
  274. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_request.py +0 -0
  275. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_research.py +0 -0
  276. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_resources.py +0 -0
  277. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_retry.py +0 -0
  278. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_routing.py +0 -0
  279. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_runtime.py +0 -0
  280. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_runtime_errors.py +0 -0
  281. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_scheduler_semantics.py +0 -0
  282. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_sessions.py +0 -0
  283. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_shutdown.py +0 -0
  284. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_skills.py +0 -0
  285. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_sources.py +0 -0
  286. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_sources_search.py +0 -0
  287. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_sources_vector.py +0 -0
  288. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_speech_provider.py +0 -0
  289. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_starter_app.py +0 -0
  290. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_streaming.py +0 -0
  291. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_structured.py +0 -0
  292. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_support_copilot.py +0 -0
  293. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_testing_assertions.py +0 -0
  294. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_testing_golden.py +0 -0
  295. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_testing_lab.py +0 -0
  296. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_testing_mock.py +0 -0
  297. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_testing_provenance.py +0 -0
  298. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_testing_pytest_plugin.py +0 -0
  299. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_testing_registry.py +0 -0
  300. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_token_budget.py +0 -0
  301. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_tools.py +0 -0
  302. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_trace_columns.py +0 -0
  303. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_trace_tags.py +0 -0
  304. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_tracing.py +0 -0
  305. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_type_registry.py +0 -0
  306. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_vendor_factories.py +0 -0
  307. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_vendor_multimodal_factories.py +0 -0
  308. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_verify.py +0 -0
  309. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_video_provider.py +0 -0
  310. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_view.py +0 -0
  311. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_viz.py +0 -0
  312. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_web_source.py +0 -0
  313. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_workspace.py +0 -0
  314. {reactifact-0.14.2 → reactifact-0.15.0}/tests/test_workspace_with_sources.py +0 -0
  315. {reactifact-0.14.2 → reactifact-0.15.0}/tests/tests_checkpoints_sqlite.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reactifact
3
- Version: 0.14.2
3
+ Version: 0.15.0
4
4
  Summary: Reactive, artifact-driven agent runtime: agents transform versioned, typed, provenance-aware artifacts inside an evolving context
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/bzdvdn/reactifact
@@ -55,7 +55,7 @@ Dynamic: license-file
55
55
  [![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue)](https://github.com/bzdvdn/reactifact)
56
56
  [![PyPI version](https://img.shields.io/pypi/v/reactifact)](https://pypi.org/project/reactifact/)
57
57
  [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
58
- [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/bzdvdn/reactifact)
58
+ [![Ask DeepWiki](docs/img/deepwiki.svg)](https://deepwiki.com/bzdvdn/reactifact)
59
59
  [![Docs](https://img.shields.io/badge/docs-bzdvdn.github.io%2Freactifact-blue)](https://bzdvdn.github.io/reactifact/)
60
60
 
61
61
  > **Is:** a Python library (3 core deps) · single-process · typed, versioned artifacts with provenance · deterministic replay · runs offline, no API key
@@ -9,7 +9,7 @@
9
9
  [![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue)](https://github.com/bzdvdn/reactifact)
10
10
  [![PyPI version](https://img.shields.io/pypi/v/reactifact)](https://pypi.org/project/reactifact/)
11
11
  [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
12
- [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/bzdvdn/reactifact)
12
+ [![Ask DeepWiki](docs/img/deepwiki.svg)](https://deepwiki.com/bzdvdn/reactifact)
13
13
  [![Docs](https://img.shields.io/badge/docs-bzdvdn.github.io%2Freactifact-blue)](https://bzdvdn.github.io/reactifact/)
14
14
 
15
15
  > **Is:** a Python library (3 core deps) · single-process · typed, versioned artifacts with provenance · deterministic replay · runs offline, no API key
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "reactifact"
7
- version = "0.14.2"
7
+ version = "0.15.0"
8
8
  description = "Reactive, artifact-driven agent runtime: agents transform versioned, typed, provenance-aware artifacts inside an evolving context"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -51,7 +51,7 @@ from .tools import FunctionTool, Tool, ToolOutput, tool
51
51
  from .triggers import Trigger
52
52
  from .types import register as register_type
53
53
 
54
- __version__ = "0.14.2"
54
+ __version__ = "0.15.0"
55
55
 
56
56
  __all__ = [
57
57
  "Agent",
@@ -41,7 +41,7 @@ from ._extras import require_extra
41
41
  from .chat import ChatAssistant, ChatEvent, ChatEventKind
42
42
 
43
43
  if TYPE_CHECKING:
44
- from fastapi import APIRouter
44
+ from fastapi import APIRouter, Request
45
45
  from fastapi.responses import JSONResponse, StreamingResponse
46
46
 
47
47
 
@@ -83,6 +83,7 @@ def create_chat_router(
83
83
  forward_kinds: Sequence[str] | None = None,
84
84
  payload_shaper: Callable[[ChatEvent], Mapping[str, Any]] | None = None,
85
85
  done_event: str | None = None,
86
+ request_factory: Callable[[Request], Mapping[str, Any]] | None = None,
86
87
  ) -> APIRouter:
87
88
  """Builds the chat router on top of a `ChatAssistant`.
88
89
 
@@ -100,6 +101,10 @@ def create_chat_router(
100
101
  - `payload_shaper(event) -> mapping` — reshape a frame's payload.
101
102
  - `done_event` — emit one extra terminal frame (e.g. `"done"`) when the
102
103
  stream ends.
104
+ - `request_factory(request) -> mapping` — build the per-turn `request=`
105
+ mapping (the same one `ChatAssistant.stream` takes) from the incoming
106
+ FastAPI `Request`, e.g. the authenticated user for ACL/identity-aware
107
+ runs. Without it the turn runs with `request=None`.
103
108
 
104
109
  Defaults reproduce the canonical contract exactly, so existing clients are
105
110
  unaffected. The event schema (`ChatEvent`) and the effective names are
@@ -108,9 +113,15 @@ def create_chat_router(
108
113
  # Readable error when the `web` extra is missing — then a regular
109
114
  # (mypy-visible) import for the real types.
110
115
  require_extra("web.create_chat_router", "fastapi", "web")
111
- from fastapi import APIRouter
116
+ from fastapi import APIRouter, Request
112
117
  from fastapi.responses import JSONResponse, StreamingResponse
113
118
 
119
+ # `Request` is only referenced from the endpoint's *string* annotation
120
+ # (`from __future__ import annotations`); FastAPI resolves those against
121
+ # the module globals, and fastapi may be absent at import time — so publish
122
+ # it lazily here, right before the endpoint that uses it is defined.
123
+ globals().setdefault("Request", Request)
124
+
114
125
  names: dict[str, str] = {k: v for k, v in DEFAULT_EVENT_NAMES.items()}
115
126
  names.update(event_names or {})
116
127
  forward = set(forward_kinds) if forward_kinds is not None else None
@@ -140,9 +151,13 @@ def create_chat_router(
140
151
  }
141
152
  },
142
153
  )
143
- async def chat_stream(req: ChatMessage) -> StreamingResponse:
154
+ async def chat_stream(req: ChatMessage, request: Request) -> StreamingResponse:
155
+ turn_request = request_factory(request) if request_factory else None
156
+
144
157
  async def stream() -> AsyncIterator[str]:
145
- async for event in assistant.stream(req.message, req.session_id):
158
+ async for event in assistant.stream(
159
+ req.message, req.session_id, request=turn_request
160
+ ):
146
161
  if forward is not None and event.kind not in forward:
147
162
  continue
148
163
  yield sse(names.get(event.kind, event.kind), dict(shaper(event)))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reactifact
3
- Version: 0.14.2
3
+ Version: 0.15.0
4
4
  Summary: Reactive, artifact-driven agent runtime: agents transform versioned, typed, provenance-aware artifacts inside an evolving context
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/bzdvdn/reactifact
@@ -55,7 +55,7 @@ Dynamic: license-file
55
55
  [![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue)](https://github.com/bzdvdn/reactifact)
56
56
  [![PyPI version](https://img.shields.io/pypi/v/reactifact)](https://pypi.org/project/reactifact/)
57
57
  [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
58
- [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/bzdvdn/reactifact)
58
+ [![Ask DeepWiki](docs/img/deepwiki.svg)](https://deepwiki.com/bzdvdn/reactifact)
59
59
  [![Docs](https://img.shields.io/badge/docs-bzdvdn.github.io%2Freactifact-blue)](https://bzdvdn.github.io/reactifact/)
60
60
 
61
61
  > **Is:** a Python library (3 core deps) · single-process · typed, versioned artifacts with provenance · deterministic replay · runs offline, no API key
@@ -157,6 +157,78 @@ def test_web_router_openapi_publishes_event_schema(tmp_path):
157
157
  assert "content" in responses["200"]["description"]
158
158
 
159
159
 
160
+ def test_web_router_request_factory_forwards_per_turn_context(tmp_path):
161
+ """`request_factory` maps the FastAPI `Request` into the turn's `request=`."""
162
+ seen: dict[str, object] = {}
163
+
164
+ async def capture(call):
165
+ seen["user"] = call.request.get("user")
166
+ call.effects.create(A(text="answer"))
167
+ return None
168
+
169
+ prod = produce(A)(capture)
170
+ agent = create_agent("cap", consumes=[Consume(Q)], produces=[prod])
171
+ store = SessionStore(FileKVBackend(os.path.join(tmp_path, "sess")))
172
+ assistant = ChatAssistant(
173
+ store=store,
174
+ agents=[agent],
175
+ user_message=Q,
176
+ reply=lambda ctx, msg_id: {"reply": "ok", "waiting": False},
177
+ max_concurrency=1,
178
+ )
179
+
180
+ app = FastAPI()
181
+ app.include_router(
182
+ create_chat_router(
183
+ assistant,
184
+ request_factory=lambda request: {"user": request.headers.get("x-user", "")},
185
+ )
186
+ )
187
+ client = TestClient(app)
188
+
189
+ with client.stream(
190
+ "POST",
191
+ "/api/chat/stream",
192
+ json={"message": "hi", "session_id": "s1"},
193
+ headers={"X-User": "alice"},
194
+ ) as response:
195
+ "".join(response.iter_text())
196
+
197
+ assert seen["user"] == "alice"
198
+
199
+
200
+ def test_web_router_without_request_factory_has_no_request(tmp_path):
201
+ """Default stays `request=None`: no behavior change for existing callers."""
202
+ seen: dict[str, object] = {}
203
+
204
+ async def capture(call):
205
+ seen["request"] = dict(call.request)
206
+ call.effects.create(A(text="answer"))
207
+ return None
208
+
209
+ prod = produce(A)(capture)
210
+ agent = create_agent("cap", consumes=[Consume(Q)], produces=[prod])
211
+ store = SessionStore(FileKVBackend(os.path.join(tmp_path, "sess")))
212
+ assistant = ChatAssistant(
213
+ store=store,
214
+ agents=[agent],
215
+ user_message=Q,
216
+ reply=lambda ctx, msg_id: {"reply": "ok", "waiting": False},
217
+ max_concurrency=1,
218
+ )
219
+
220
+ app = FastAPI()
221
+ app.include_router(create_chat_router(assistant))
222
+ client = TestClient(app)
223
+
224
+ with client.stream(
225
+ "POST", "/api/chat/stream", json={"message": "hi", "session_id": "s1"}
226
+ ) as response:
227
+ "".join(response.iter_text())
228
+
229
+ assert seen["request"] == {}
230
+
231
+
160
232
  def test_disconnect_cancels_the_running_turn(tmp_path):
161
233
  """A dropped SSE client must cancel in-flight work, not leave it burning.
162
234
 
File without changes