reactifact 0.14.0__tar.gz → 0.14.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 (315) hide show
  1. {reactifact-0.14.0/reactifact.egg-info → reactifact-0.14.1}/PKG-INFO +1 -1
  2. {reactifact-0.14.0 → reactifact-0.14.1}/pyproject.toml +1 -1
  3. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/__init__.py +1 -1
  4. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/chat.py +14 -1
  5. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/quick/chat.py +5 -0
  6. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/runtime.py +3 -3
  7. {reactifact-0.14.0 → reactifact-0.14.1/reactifact.egg-info}/PKG-INFO +1 -1
  8. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact.egg-info/SOURCES.txt +1 -0
  9. reactifact-0.14.1/tests/test_chat_outbox.py +70 -0
  10. {reactifact-0.14.0 → reactifact-0.14.1}/LICENSE +0 -0
  11. {reactifact-0.14.0 → reactifact-0.14.1}/README.md +0 -0
  12. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/__main__.py +0 -0
  13. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/_extras.py +0 -0
  14. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/_httpx.py +0 -0
  15. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/a2a/__init__.py +0 -0
  16. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/a2a/client.py +0 -0
  17. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/a2a/models.py +0 -0
  18. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/a2a/remote.py +0 -0
  19. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/a2a/server.py +0 -0
  20. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/agent_tool.py +0 -0
  21. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/agents.py +0 -0
  22. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/artifacts.py +0 -0
  23. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/audit.py +0 -0
  24. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/authz.py +0 -0
  25. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/branching.py +0 -0
  26. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/budget.py +0 -0
  27. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/cache.py +0 -0
  28. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/checkpoints.py +0 -0
  29. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/cli/__init__.py +0 -0
  30. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/cli/branch.py +0 -0
  31. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/cli/common.py +0 -0
  32. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/cli/context.py +0 -0
  33. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/cli/eval.py +0 -0
  34. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/cli/graph.py +0 -0
  35. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/cli/replay.py +0 -0
  36. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/cli/scenario.py +0 -0
  37. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/cli/skills.py +0 -0
  38. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/cli/trace.py +0 -0
  39. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/commit.py +0 -0
  40. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/commit_log.py +0 -0
  41. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/consume.py +0 -0
  42. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/context.py +0 -0
  43. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/context_builder.py +0 -0
  44. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/effects.py +0 -0
  45. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/eval/__init__.py +0 -0
  46. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/eval/dataset.py +0 -0
  47. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/eval/evaluators.py +0 -0
  48. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/eval/judge.py +0 -0
  49. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/eval/online.py +0 -0
  50. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/eval/runner.py +0 -0
  51. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/eval/scoring.py +0 -0
  52. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/events.py +0 -0
  53. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/guardrails.py +0 -0
  54. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/interrupt.py +0 -0
  55. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/llm_agent.py +0 -0
  56. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/logging.py +0 -0
  57. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/mcp/__init__.py +0 -0
  58. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/mcp/client.py +0 -0
  59. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/mcp/oauth.py +0 -0
  60. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/mcp/server.py +0 -0
  61. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/metrics.py +0 -0
  62. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/native_tool_use.py +0 -0
  63. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/operations.py +0 -0
  64. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/patches.py +0 -0
  65. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/pricing.py +0 -0
  66. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/produce.py +0 -0
  67. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/prompts.py +0 -0
  68. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/__init__.py +0 -0
  69. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/_retry.py +0 -0
  70. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/anthropic.py +0 -0
  71. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/azure.py +0 -0
  72. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/cerebras.py +0 -0
  73. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/chat.py +0 -0
  74. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/contracts.py +0 -0
  75. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/deepseek.py +0 -0
  76. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/fake.py +0 -0
  77. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/fireworks.py +0 -0
  78. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/gemini.py +0 -0
  79. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/github_models.py +0 -0
  80. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/groq.py +0 -0
  81. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/image.py +0 -0
  82. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/mistral.py +0 -0
  83. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/nvidia.py +0 -0
  84. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/ollama.py +0 -0
  85. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/openai.py +0 -0
  86. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/openrouter.py +0 -0
  87. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/perplexity.py +0 -0
  88. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/qwen.py +0 -0
  89. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/speech.py +0 -0
  90. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/together.py +0 -0
  91. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/video.py +0 -0
  92. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/xai.py +0 -0
  93. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/providers/zai.py +0 -0
  94. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/py.typed +0 -0
  95. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/quick/__init__.py +0 -0
  96. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/quick/_shared.py +0 -0
  97. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/quick/agent.py +0 -0
  98. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/quick/models.py +0 -0
  99. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/quick/rag.py +0 -0
  100. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/quick/tools_agent.py +0 -0
  101. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/quota.py +0 -0
  102. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/recipes/__init__.py +0 -0
  103. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/recipes/cleanup.py +0 -0
  104. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/recipes/conversation.py +0 -0
  105. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/recipes/identity.py +0 -0
  106. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/recipes/inputs.py +0 -0
  107. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/recipes/memory.py +0 -0
  108. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/recipes/plan_execute.py +0 -0
  109. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/recipes/reflection.py +0 -0
  110. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/recipes/resolve.py +0 -0
  111. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/recipes/rollback.py +0 -0
  112. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/recipes/search.py +0 -0
  113. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/recipes/skills.py +0 -0
  114. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/recipes/status.py +0 -0
  115. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/recipes/supervisor.py +0 -0
  116. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/recipes/text.py +0 -0
  117. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/recipes/tool_loop.py +0 -0
  118. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/redaction.py +0 -0
  119. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/relations.py +0 -0
  120. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/replay.py +0 -0
  121. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/request.py +0 -0
  122. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/resources.py +0 -0
  123. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/routing.py +0 -0
  124. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/scheduler.py +0 -0
  125. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/session.py +0 -0
  126. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/skills/reactifact/SKILL.md +0 -0
  127. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/skills/reactifact/references/effects-and-state.md +0 -0
  128. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/skills/reactifact/references/trust-and-safety.md +0 -0
  129. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/skills/reactifact-agents/SKILL.md +0 -0
  130. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/skills/reactifact-agents/references/consume.md +0 -0
  131. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/skills/reactifact-agents/references/effects.md +0 -0
  132. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/skills/reactifact-eval/SKILL.md +0 -0
  133. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/skills/reactifact-eval/references/online.md +0 -0
  134. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/skills/reactifact-from-langchain/SKILL.md +0 -0
  135. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/skills/reactifact-llm/SKILL.md +0 -0
  136. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/skills/reactifact-llm/references/providers.md +0 -0
  137. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/skills/reactifact-llm/references/tools.md +0 -0
  138. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/skills/reactifact-observability/SKILL.md +0 -0
  139. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/skills/reactifact-rag/SKILL.md +0 -0
  140. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/skills/reactifact-rag/references/sources.md +0 -0
  141. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/skills/reactifact-testing/SKILL.md +0 -0
  142. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/sources.py +0 -0
  143. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/streaming.py +0 -0
  144. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/structured.py +0 -0
  145. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/testing/__init__.py +0 -0
  146. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/testing/assertions.py +0 -0
  147. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/testing/exceptions.py +0 -0
  148. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/testing/fault.py +0 -0
  149. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/testing/golden.py +0 -0
  150. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/testing/lab.py +0 -0
  151. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/testing/mock.py +0 -0
  152. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/testing/pytest_plugin.py +0 -0
  153. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/testing/record.py +0 -0
  154. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/testing/registry.py +0 -0
  155. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/tool_use.py +0 -0
  156. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/tools.py +0 -0
  157. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/tracing/__init__.py +0 -0
  158. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/tracing/_otlp.py +0 -0
  159. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/tracing/columns.py +0 -0
  160. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/tracing/langfuse.py +0 -0
  161. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/tracing/models.py +0 -0
  162. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/tracing/otlp.py +0 -0
  163. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/tracing/postgres.py +0 -0
  164. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/tracing/store.py +0 -0
  165. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/tracing/templates/app.css +0 -0
  166. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/tracing/templates/sessions.html +0 -0
  167. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/tracing/templates/ui.html +0 -0
  168. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/tracing/templates/ui_run.html +0 -0
  169. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/tracing/tracer.py +0 -0
  170. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/tracing/web.py +0 -0
  171. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/triggers.py +0 -0
  172. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/types.py +0 -0
  173. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/verify.py +0 -0
  174. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/viz.py +0 -0
  175. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact/web.py +0 -0
  176. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact.egg-info/dependency_links.txt +0 -0
  177. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact.egg-info/entry_points.txt +0 -0
  178. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact.egg-info/requires.txt +0 -0
  179. {reactifact-0.14.0 → reactifact-0.14.1}/reactifact.egg-info/top_level.txt +0 -0
  180. {reactifact-0.14.0 → reactifact-0.14.1}/setup.cfg +0 -0
  181. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_a2a.py +0 -0
  182. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_a2a_example.py +0 -0
  183. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_a2a_interop.py +0 -0
  184. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_absent_consume.py +0 -0
  185. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_adaptive.py +0 -0
  186. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_agent_tool.py +0 -0
  187. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_anthropic_provider.py +0 -0
  188. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_artifacts.py +0 -0
  189. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_audit.py +0 -0
  190. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_authz.py +0 -0
  191. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_backbone.py +0 -0
  192. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_branching.py +0 -0
  193. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_budget.py +0 -0
  194. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_cache.py +0 -0
  195. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_canonical_ports.py +0 -0
  196. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_chat_example.py +0 -0
  197. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_chat_memory.py +0 -0
  198. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_chat_web.py +0 -0
  199. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_checkpoint.py +0 -0
  200. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_checkpoints_concurrency.py +0 -0
  201. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_cli.py +0 -0
  202. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_cli_scenario.py +0 -0
  203. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_commit_log.py +0 -0
  204. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_compaction.py +0 -0
  205. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_concurrency.py +0 -0
  206. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_consumes_produces.py +0 -0
  207. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_context_builder.py +0 -0
  208. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_correlated_consume.py +0 -0
  209. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_debounce.py +0 -0
  210. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_determinism.py +0 -0
  211. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_devops.py +0 -0
  212. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_devops_online.py +0 -0
  213. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_devops_web.py +0 -0
  214. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_effects.py +0 -0
  215. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_eval.py +0 -0
  216. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_eval_dataset.py +0 -0
  217. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_eval_judge.py +0 -0
  218. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_eval_online.py +0 -0
  219. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_eval_trajectory.py +0 -0
  220. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_fintech_audit.py +0 -0
  221. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_forklab.py +0 -0
  222. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_forklab_web.py +0 -0
  223. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_friendly_api.py +0 -0
  224. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_gemini_provider.py +0 -0
  225. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_golden.py +0 -0
  226. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_guardrails.py +0 -0
  227. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_hitl.py +0 -0
  228. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_image_provider.py +0 -0
  229. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_incident_commander.py +0 -0
  230. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_invalidation.py +0 -0
  231. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_join_consume.py +0 -0
  232. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_knowledge.py +0 -0
  233. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_knowledge_web.py +0 -0
  234. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_llm_ladder.py +0 -0
  235. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_logging.py +0 -0
  236. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_loop_bound_client.py +0 -0
  237. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_mcp.py +0 -0
  238. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_medic_lab.py +0 -0
  239. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_medic_lab_web.py +0 -0
  240. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_metrics.py +0 -0
  241. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_multisource.py +0 -0
  242. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_native_tool_use.py +0 -0
  243. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_openai_provider.py +0 -0
  244. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_outbox.py +0 -0
  245. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_patches.py +0 -0
  246. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_pending_actions.py +0 -0
  247. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_ports.py +0 -0
  248. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_produce_styles.py +0 -0
  249. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_produce_trigger.py +0 -0
  250. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_prompts.py +0 -0
  251. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_provider_auth.py +0 -0
  252. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_provider_retry.py +0 -0
  253. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_providers_integration.py +0 -0
  254. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_public_api.py +0 -0
  255. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_quick.py +0 -0
  256. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_quota.py +0 -0
  257. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_reacts_to.py +0 -0
  258. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_recipe_conversation.py +0 -0
  259. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_recipe_plan_execute.py +0 -0
  260. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_recipe_reflection.py +0 -0
  261. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_recipe_supervisor.py +0 -0
  262. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_recipe_tool_loop.py +0 -0
  263. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_recipes.py +0 -0
  264. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_recipes_inputs.py +0 -0
  265. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_recipes_memory.py +0 -0
  266. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_recipes_skills.py +0 -0
  267. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_redaction.py +0 -0
  268. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_relation_graph.py +0 -0
  269. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_relations.py +0 -0
  270. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_repair.py +0 -0
  271. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_repair_web.py +0 -0
  272. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_replay.py +0 -0
  273. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_repo_agent.py +0 -0
  274. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_request.py +0 -0
  275. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_research.py +0 -0
  276. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_resources.py +0 -0
  277. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_retry.py +0 -0
  278. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_routing.py +0 -0
  279. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_runtime.py +0 -0
  280. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_runtime_errors.py +0 -0
  281. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_scheduler_semantics.py +0 -0
  282. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_sessions.py +0 -0
  283. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_shutdown.py +0 -0
  284. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_skills.py +0 -0
  285. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_sources.py +0 -0
  286. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_sources_search.py +0 -0
  287. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_sources_vector.py +0 -0
  288. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_speech_provider.py +0 -0
  289. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_starter_app.py +0 -0
  290. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_streaming.py +0 -0
  291. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_structured.py +0 -0
  292. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_support_copilot.py +0 -0
  293. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_testing_assertions.py +0 -0
  294. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_testing_golden.py +0 -0
  295. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_testing_lab.py +0 -0
  296. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_testing_mock.py +0 -0
  297. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_testing_provenance.py +0 -0
  298. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_testing_pytest_plugin.py +0 -0
  299. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_testing_registry.py +0 -0
  300. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_token_budget.py +0 -0
  301. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_tools.py +0 -0
  302. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_trace_columns.py +0 -0
  303. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_trace_tags.py +0 -0
  304. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_tracing.py +0 -0
  305. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_type_registry.py +0 -0
  306. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_vendor_factories.py +0 -0
  307. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_vendor_multimodal_factories.py +0 -0
  308. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_verify.py +0 -0
  309. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_video_provider.py +0 -0
  310. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_view.py +0 -0
  311. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_viz.py +0 -0
  312. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_web_source.py +0 -0
  313. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_workspace.py +0 -0
  314. {reactifact-0.14.0 → reactifact-0.14.1}/tests/test_workspace_with_sources.py +0 -0
  315. {reactifact-0.14.0 → reactifact-0.14.1}/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.0
3
+ Version: 0.14.1
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "reactifact"
7
- version = "0.14.0"
7
+ version = "0.14.1"
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.0"
54
+ __version__ = "0.14.1"
55
55
 
56
56
  __all__ = [
57
57
  "Agent",
@@ -38,7 +38,7 @@ from .consume import Consume
38
38
  from .context import Context
39
39
  from .events import Event
40
40
  from .resources import RuntimeResources
41
- from .runtime import Runtime
41
+ from .runtime import Dispatcher, DispatchErrorHandler, Runtime
42
42
  from .session import Session, SessionStore
43
43
 
44
44
  logger = logging.getLogger("reactifact.chat")
@@ -306,6 +306,13 @@ class ChatAssistant:
306
306
  multi-stage pipeline routinely produces several generations per turn (see
307
307
  `Runtime.__init__`'s own docstring for the trade-off).
308
308
 
309
+ `dispatcher=` (and `on_dispatch_error=`) also passes straight through to
310
+ `Runtime`: give an agent that uses `effects.act(...)` a way to actually send
311
+ its outbound side effects from a chat turn, with the same once-per-stable-id
312
+ delivery `Runtime(dispatcher=...)` provides. Without it, a chat turn that
313
+ records a `PendingAction` leaves it `pending` (the runtime warns) for someone
314
+ to drain later.
315
+
309
316
  `resources=`/`create_message=` may optionally take the current turn's
310
317
  `session_id` — `resources=lambda session_id: build_resources(session_id)`
311
318
  (e.g. to attach an authenticated user looked up from the session) and
@@ -349,6 +356,8 @@ class ChatAssistant:
349
356
  on_agent_error: Callable[[Agent, Event, BaseException], None] | None = None,
350
357
  session_save_policy: Literal["per_commit", "per_turn"] = "per_commit",
351
358
  memory: ChatMemory | None = None,
359
+ dispatcher: Dispatcher | None = None,
360
+ on_dispatch_error: DispatchErrorHandler | None = None,
352
361
  ):
353
362
  self.store = store
354
363
  self._agents = agents
@@ -368,6 +377,8 @@ class ChatAssistant:
368
377
  session_save_policy
369
378
  )
370
379
  self._memory = memory
380
+ self._dispatcher = dispatcher
381
+ self._on_dispatch_error = on_dispatch_error
371
382
  # Serializes concurrent turns on the *same* session_id (a double
372
383
  # submit, a client retry): without this, two overlapping stream()
373
384
  # calls both load the same starting state and the later save() wins,
@@ -453,6 +464,8 @@ class ChatAssistant:
453
464
  isolate_errors=self._isolate_errors,
454
465
  on_agent_error=self._on_agent_error,
455
466
  session_save_policy=self._session_save_policy,
467
+ dispatcher=self._dispatcher,
468
+ on_dispatch_error=self._on_dispatch_error,
456
469
  )
457
470
 
458
471
  async def stream(
@@ -15,6 +15,7 @@ from ..checkpoints import FileKVBackend, InMemoryKVBackend
15
15
  from ..context import Context
16
16
  from ..providers import LLMProvider, from_env
17
17
  from ..resources import RuntimeResources
18
+ from ..runtime import Dispatcher, DispatchErrorHandler
18
19
  from ..session import SessionStore
19
20
  from .models import Question
20
21
 
@@ -54,6 +55,8 @@ def chat_agent(
54
55
  resources: RuntimeResources | Callable[..., RuntimeResources] | None = None,
55
56
  budget: Budget | None = None,
56
57
  tracer: Any = None,
58
+ dispatcher: Dispatcher | None = None,
59
+ on_dispatch_error: DispatchErrorHandler | None = None,
57
60
  ) -> ChatAssistant:
58
61
  """A configured `ChatAssistant` — sessions, turns, history, out of the box.
59
62
 
@@ -79,6 +82,8 @@ def chat_agent(
79
82
  resources=resources,
80
83
  budget=budget,
81
84
  tracer=tracer,
85
+ dispatcher=dispatcher,
86
+ on_dispatch_error=on_dispatch_error,
82
87
  )
83
88
 
84
89
 
@@ -38,6 +38,8 @@ AgentResult = tuple[Patch | None, Agent, Event, list[Read], float, BaseException
38
38
  #: the intent is committed; the app performs the real I/O and returns (or
39
39
  #: raises). Must be idempotent on `idempotency_key` (§42).
40
40
  Dispatcher = Callable[[Context, Artifact[PendingAction]], Awaitable[None]]
41
+ #: Called when the dispatcher raises (the action is already marked `failed`).
42
+ DispatchErrorHandler = Callable[[Artifact[PendingAction], BaseException], None]
41
43
 
42
44
 
43
45
  @dataclass
@@ -93,9 +95,7 @@ class Runtime:
93
95
  on_agent_error: Callable[[Agent, Event, BaseException], None] | None = None,
94
96
  session_save_policy: Literal["per_commit", "per_turn"] = "per_commit",
95
97
  dispatcher: Dispatcher | None = None,
96
- on_dispatch_error: (
97
- Callable[[Artifact[PendingAction], BaseException], None] | None
98
- ) = None,
98
+ on_dispatch_error: DispatchErrorHandler | None = None,
99
99
  ):
100
100
  self.context = context
101
101
  self.agents = agents or []
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reactifact
3
- Version: 0.14.0
3
+ Version: 0.14.1
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
@@ -192,6 +192,7 @@ tests/test_cache.py
192
192
  tests/test_canonical_ports.py
193
193
  tests/test_chat_example.py
194
194
  tests/test_chat_memory.py
195
+ tests/test_chat_outbox.py
195
196
  tests/test_chat_web.py
196
197
  tests/test_checkpoint.py
197
198
  tests/test_checkpoints_concurrency.py
@@ -0,0 +1,70 @@
1
+ """`ChatAssistant(dispatcher=...)` — outbound side effects from a chat turn."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+
7
+ from pydantic import BaseModel
8
+ from reactifact import PendingAction
9
+ from reactifact.agents import create_agent
10
+ from reactifact.chat import ChatAssistant
11
+ from reactifact.checkpoints import InMemoryKVBackend
12
+ from reactifact.consume import Consume
13
+ from reactifact.context import Context
14
+ from reactifact.produce import Produce, ProduceCall
15
+ from reactifact.session import SessionStore
16
+
17
+
18
+ class _Msg(BaseModel):
19
+ text: str
20
+
21
+
22
+ class _Reply(BaseModel):
23
+ text: str
24
+
25
+
26
+ class _Notifier(Produce[_Reply]):
27
+ artifact_type = _Reply
28
+ also_creates = (PendingAction,)
29
+
30
+ async def produce(self, call: ProduceCall) -> None:
31
+ msg = call.trigger
32
+ if msg is None:
33
+ return
34
+ call.effects.act(
35
+ "notify", key=f"notify:{msg.data.text}", payload={"text": msg.data.text}
36
+ )
37
+ call.effects.create(_Reply(text=f"noted: {msg.data.text}"), id="reply:1")
38
+
39
+
40
+ def _reply(ctx: Context, _message_id: str) -> dict[str, str]:
41
+ replies = ctx.list_artifacts(_Reply)
42
+ return {"reply": replies[-1].data.text if replies else ""}
43
+
44
+
45
+ def test_chat_assistant_runs_the_outbox_dispatcher():
46
+ sent: list[str] = []
47
+
48
+ async def dispatcher(context: Context, action) -> None:
49
+ sent.append(action.data.idempotency_key)
50
+
51
+ store = SessionStore(InMemoryKVBackend())
52
+ assistant = ChatAssistant(
53
+ store=store,
54
+ agents=[
55
+ create_agent("notify", consumes=[Consume(_Msg)], produces=[_Notifier()])
56
+ ],
57
+ user_message=_Msg,
58
+ reply=_reply,
59
+ dispatcher=dispatcher,
60
+ )
61
+
62
+ result = asyncio.run(assistant.invoke("hi", session_id="s1"))
63
+
64
+ assert result["reply"] == "noted: hi"
65
+ assert sent == ["notify:hi"]
66
+
67
+ session = asyncio.run(store.open("s1"))
68
+ action = session.context.get("action:notify:hi")
69
+ assert action is not None
70
+ assert action.data.status == "dispatched"
File without changes
File without changes