deepstrike 0.2.44__tar.gz → 0.2.46__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 (190) hide show
  1. {deepstrike-0.2.44 → deepstrike-0.2.46}/Cargo.lock +6 -6
  2. {deepstrike-0.2.44 → deepstrike-0.2.46}/Cargo.toml +2 -2
  3. {deepstrike-0.2.44 → deepstrike-0.2.46}/PKG-INFO +1 -1
  4. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/runtime/kernel/runtime.rs +13 -0
  5. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/runtime/kernel/tests.rs +29 -0
  6. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/scheduler/state_machine/mod.rs +44 -19
  7. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/scheduler/state_machine/tests.rs +28 -0
  8. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/execution_plane.py +6 -3
  9. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/runner.py +26 -10
  10. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/sub_agent_orchestrator.py +18 -0
  11. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/tools/execution.py +3 -1
  12. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/tools/registry.py +60 -2
  13. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/types/agent.py +7 -0
  14. {deepstrike-0.2.44 → deepstrike-0.2.46}/pyproject.toml +1 -1
  15. {deepstrike-0.2.44 → deepstrike-0.2.46}/README.md +0 -0
  16. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/Cargo.toml +0 -0
  17. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/benches/kernel_baseline.rs +0 -0
  18. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/benchmark/mod.rs +0 -0
  19. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/context/compression.rs +0 -0
  20. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/context/config.rs +0 -0
  21. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/context/fault.rs +0 -0
  22. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/context/manager.rs +0 -0
  23. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/context/mod.rs +0 -0
  24. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/context/partitions.rs +0 -0
  25. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/context/policy.rs +0 -0
  26. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/context/pressure.rs +0 -0
  27. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/context/renderer.rs +0 -0
  28. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/context/renewal.rs +0 -0
  29. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/context/skill_catalog.rs +0 -0
  30. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/context/summarizer.rs +0 -0
  31. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/context/task_state.rs +0 -0
  32. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/context/text.rs +0 -0
  33. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/context/token_engine.rs +0 -0
  34. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/context/units.rs +0 -0
  35. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/context/utility.rs +0 -0
  36. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/governance/constraint.rs +0 -0
  37. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/governance/mod.rs +0 -0
  38. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/governance/permission.rs +0 -0
  39. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/governance/pipeline.rs +0 -0
  40. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/governance/quota.rs +0 -0
  41. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/governance/rate_limit.rs +0 -0
  42. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/governance/repeat_fuse.rs +0 -0
  43. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/governance/veto.rs +0 -0
  44. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/harness/eval.rs +0 -0
  45. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/harness/mod.rs +0 -0
  46. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/lexical.rs +0 -0
  47. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/lib.rs +0 -0
  48. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/memory/curator.rs +0 -0
  49. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/memory/durable.rs +0 -0
  50. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/memory/mod.rs +0 -0
  51. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/mm/handle.rs +0 -0
  52. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/mm/memory.rs +0 -0
  53. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/mm/mod.rs +0 -0
  54. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/mm/value.rs +0 -0
  55. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/orchestration/mod.rs +0 -0
  56. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/orchestration/task_graph.rs +0 -0
  57. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/orchestration/tournament.rs +0 -0
  58. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/orchestration/workflow/mod.rs +0 -0
  59. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/orchestration/workflow/run.rs +0 -0
  60. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/proc/mod.rs +0 -0
  61. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/runtime/event_log.rs +0 -0
  62. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/runtime/kernel/protocol.rs +0 -0
  63. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/runtime/kernel.rs +0 -0
  64. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/runtime/mod.rs +0 -0
  65. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/runtime/repair.rs +0 -0
  66. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/runtime/replay.rs +0 -0
  67. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/runtime/session.rs +0 -0
  68. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/scheduler/entropy.rs +0 -0
  69. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/scheduler/milestone.rs +0 -0
  70. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/scheduler/mod.rs +0 -0
  71. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/scheduler/policy.rs +0 -0
  72. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/scheduler/rollback.rs +0 -0
  73. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/scheduler/state_machine/cancellation.rs +0 -0
  74. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/scheduler/state_machine/capability.rs +0 -0
  75. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/scheduler/state_machine/eviction.rs +0 -0
  76. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/scheduler/state_machine/gate.rs +0 -0
  77. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/scheduler/state_machine/milestone_exec.rs +0 -0
  78. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/scheduler/state_machine/process.rs +0 -0
  79. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/scheduler/state_machine/signal.rs +0 -0
  80. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/scheduler/state_machine/workflow.rs +0 -0
  81. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/scheduler/tcb.rs +0 -0
  82. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/signals/attention.rs +0 -0
  83. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/signals/mod.rs +0 -0
  84. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/signals/queue.rs +0 -0
  85. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/signals/router.rs +0 -0
  86. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/syscall/mod.rs +0 -0
  87. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/types/agent.rs +0 -0
  88. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/types/capability.rs +0 -0
  89. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/types/contract.rs +0 -0
  90. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/types/error.rs +0 -0
  91. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/types/message.rs +0 -0
  92. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/types/milestone.rs +0 -0
  93. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/types/mod.rs +0 -0
  94. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/types/policy.rs +0 -0
  95. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/types/result.rs +0 -0
  96. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/types/signal.rs +0 -0
  97. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/types/skill.rs +0 -0
  98. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-core/src/types/task.rs +0 -0
  99. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-py/Cargo.toml +0 -0
  100. {deepstrike-0.2.44 → deepstrike-0.2.46}/crates/deepstrike-py/src/lib.rs +0 -0
  101. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/__init__.py +0 -0
  102. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/collaboration/__init__.py +0 -0
  103. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/collaboration/contract.py +0 -0
  104. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/collaboration/handoff.py +0 -0
  105. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/collaboration/harness.py +0 -0
  106. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/collaboration/modes.py +0 -0
  107. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/collaboration/pool.py +0 -0
  108. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/governance.py +0 -0
  109. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/harness/__init__.py +0 -0
  110. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/harness/harness.py +0 -0
  111. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/harness/judge.py +0 -0
  112. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/kernel/__init__.py +0 -0
  113. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/knowledge/__init__.py +0 -0
  114. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/knowledge/source.py +0 -0
  115. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/memory/__init__.py +0 -0
  116. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/memory/agent.py +0 -0
  117. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/memory/extraction.py +0 -0
  118. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/memory/in_memory_store.py +0 -0
  119. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/memory/protocols.py +0 -0
  120. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/memory/ranking.py +0 -0
  121. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/memory/retention.py +0 -0
  122. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/memory/working.py +0 -0
  123. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/providers/__init__.py +0 -0
  124. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/providers/anthropic.py +0 -0
  125. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/providers/anthropic_compatible.py +0 -0
  126. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/providers/base.py +0 -0
  127. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/providers/deepseek.py +0 -0
  128. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/providers/factories.py +0 -0
  129. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/providers/gemini.py +0 -0
  130. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/providers/glm.py +0 -0
  131. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/providers/kimi.py +0 -0
  132. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/providers/minimax.py +0 -0
  133. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/providers/ollama.py +0 -0
  134. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/providers/openai.py +0 -0
  135. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/providers/openai_responses.py +0 -0
  136. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/providers/qwen.py +0 -0
  137. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/providers/replay.py +0 -0
  138. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/providers/replay_validator.py +0 -0
  139. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/providers/stream.py +0 -0
  140. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/providers/vendor_profiles.py +0 -0
  141. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/__init__.py +0 -0
  142. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/archive.py +0 -0
  143. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/context_policy.py +0 -0
  144. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/credential_vault.py +0 -0
  145. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/eval.py +0 -0
  146. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/event_stream.py +0 -0
  147. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/facade.py +0 -0
  148. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/filtered_plane.py +0 -0
  149. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/kernel_event_log.py +0 -0
  150. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/kernel_rebuild.py +0 -0
  151. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/kernel_step.py +0 -0
  152. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/kernel_transaction_log.py +0 -0
  153. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/large_result_spool.py +0 -0
  154. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/loop_driver.py +0 -0
  155. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/mcp_proxy_plane.py +0 -0
  156. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/os_profile.py +0 -0
  157. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/os_snapshot.py +0 -0
  158. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/output_schema.py +0 -0
  159. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/process_sandbox_plane.py +0 -0
  160. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/provider_replay.py +0 -0
  161. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/reaction_checkpoint.py +0 -0
  162. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/reactive_session.py +0 -0
  163. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/reducers.py +0 -0
  164. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/reliability.py +0 -0
  165. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/remote_vpc_plane.py +0 -0
  166. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/replay_fixture.py +0 -0
  167. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/replay_provider.py +0 -0
  168. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/replay_sanitize.py +0 -0
  169. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/run_group.py +0 -0
  170. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/session_log.py +0 -0
  171. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/session_repair.py +0 -0
  172. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/turn_policy.py +0 -0
  173. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/workflow_control_flow.py +0 -0
  174. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/workflow_store.py +0 -0
  175. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/runtime/worktree_plane.py +0 -0
  176. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/safety/__init__.py +0 -0
  177. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/safety/permissions.py +0 -0
  178. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/signals/__init__.py +0 -0
  179. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/signals/gateway.py +0 -0
  180. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/signals/scheduled.py +0 -0
  181. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/signals/types.py +0 -0
  182. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/skills/__init__.py +0 -0
  183. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/skills/loader.py +0 -0
  184. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/skills/registry.py +0 -0
  185. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/skills/watcher.py +0 -0
  186. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/tools/__init__.py +0 -0
  187. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/tools/builtin/__init__.py +0 -0
  188. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/tools/builtin/read_file.py +0 -0
  189. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/tools/errors.py +0 -0
  190. {deepstrike-0.2.44 → deepstrike-0.2.46}/deepstrike/types/__init__.py +0 -0
@@ -194,7 +194,7 @@ dependencies = [
194
194
 
195
195
  [[package]]
196
196
  name = "deepstrike-core"
197
- version = "0.2.44"
197
+ version = "0.2.46"
198
198
  dependencies = [
199
199
  "compact_str",
200
200
  "pretty_assertions",
@@ -206,7 +206,7 @@ dependencies = [
206
206
 
207
207
  [[package]]
208
208
  name = "deepstrike-lab"
209
- version = "0.2.44"
209
+ version = "0.2.46"
210
210
  dependencies = [
211
211
  "deepstrike-core",
212
212
  "serde",
@@ -216,7 +216,7 @@ dependencies = [
216
216
 
217
217
  [[package]]
218
218
  name = "deepstrike-node"
219
- version = "0.2.44"
219
+ version = "0.2.46"
220
220
  dependencies = [
221
221
  "compact_str",
222
222
  "deepstrike-core",
@@ -228,7 +228,7 @@ dependencies = [
228
228
 
229
229
  [[package]]
230
230
  name = "deepstrike-py"
231
- version = "0.2.44"
231
+ version = "0.2.46"
232
232
  dependencies = [
233
233
  "compact_str",
234
234
  "deepstrike-core",
@@ -239,7 +239,7 @@ dependencies = [
239
239
 
240
240
  [[package]]
241
241
  name = "deepstrike-sdk"
242
- version = "0.2.44"
242
+ version = "0.2.46"
243
243
  dependencies = [
244
244
  "async-stream",
245
245
  "async-trait",
@@ -273,7 +273,7 @@ dependencies = [
273
273
 
274
274
  [[package]]
275
275
  name = "deepstrike-wasm"
276
- version = "0.2.44"
276
+ version = "0.2.46"
277
277
  dependencies = [
278
278
  "compact_str",
279
279
  "deepstrike-core",
@@ -3,13 +3,13 @@ resolver = "2"
3
3
  members = ["crates/deepstrike-core", "crates/deepstrike-py"]
4
4
 
5
5
  [workspace.package]
6
- version = "0.2.44"
6
+ version = "0.2.46"
7
7
  edition = "2024"
8
8
  license = "MIT"
9
9
  repository = "https://github.com/kongusen/deepstrike"
10
10
 
11
11
  [workspace.dependencies]
12
- deepstrike-core = { path = "crates/deepstrike-core", version = "0.2.44" }
12
+ deepstrike-core = { path = "crates/deepstrike-core", version = "0.2.46" }
13
13
  notify = "6"
14
14
  serde = { version = "1", features = ["derive"] }
15
15
  serde_json = "1"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepstrike
3
- Version: 0.2.44
3
+ Version: 0.2.46
4
4
  Requires-Dist: httpx>=0.27
5
5
  Requires-Dist: pyyaml>=6.0
6
6
  Requires-Dist: anyio>=4.0
@@ -2352,6 +2352,19 @@ fn validate_run_config(config: &RunConfig, max_tokens: u32) -> Result<(), String
2352
2352
  {
2353
2353
  return Err("budget_grant reservation_id must be non-empty".to_string());
2354
2354
  }
2355
+ // A zero-token grant admits no runnable work: the run would silently degrade to a
2356
+ // tool-less final round. Reject it at admission so the host surfaces the exhausted
2357
+ // reservation instead of a phantom completion.
2358
+ if let Some(grant) = config
2359
+ .budget_grant
2360
+ .as_ref()
2361
+ .filter(|grant| grant.tokens == Some(0))
2362
+ {
2363
+ return Err(format!(
2364
+ "budget_grant tokens must be positive (zero-token grant admits no runnable work), reservation_id={}",
2365
+ grant.reservation_id
2366
+ ));
2367
+ }
2355
2368
  if let Some(reliability) = &config.reliability {
2356
2369
  for (name, capacity) in [
2357
2370
  ("event_replay_capacity", reliability.event_replay_capacity),
@@ -167,6 +167,35 @@ fn prompt_reservations_cannot_consume_the_entire_context_window() {
167
167
  ));
168
168
  }
169
169
 
170
+ #[test]
171
+ fn zero_token_budget_grant_is_rejected_at_configure() {
172
+ let mut runtime = KernelRuntime::new(SchedulerBudget::default());
173
+ let rejected = runtime.step(KernelInput::new(KernelInputEvent::ConfigureRun {
174
+ config: RunConfig {
175
+ budget_grant: Some(BudgetGrant {
176
+ reservation_id: "r0".into(),
177
+ tokens: Some(0),
178
+ subagents: None,
179
+ rounds: None,
180
+ }),
181
+ ..RunConfig::default()
182
+ },
183
+ }));
184
+
185
+ assert!(matches!(
186
+ rejected.faults.as_slice(),
187
+ [KernelFault {
188
+ code: KernelFaultCode::InvalidConfig,
189
+ ..
190
+ }]
191
+ ));
192
+ assert!(
193
+ rejected.faults[0].message.contains("r0"),
194
+ "fault message must name the rejected reservation: {}",
195
+ rejected.faults[0].message
196
+ );
197
+ }
198
+
170
199
  #[test]
171
200
  fn aborting_prepared_step_restores_the_exact_committed_runtime() {
172
201
  let mut runtime = KernelRuntime::new(SchedulerBudget::default());
@@ -829,29 +829,54 @@ impl LoopStateMachine {
829
829
  // A loop vehicle with no admitted round capacity must not make even one provider call.
830
830
  // The host may have raced another member between reading its durable loop log and reserve;
831
831
  // the reservation is the authoritative admission decision.
832
- if self
832
+ let zero_round_grant = self
833
833
  .run_spec
834
834
  .as_ref()
835
835
  .and_then(|spec| spec.loop_round.as_ref())
836
836
  .is_some()
837
- && self.budget_grant.as_ref().and_then(|grant| grant.rounds) == Some(0)
838
- {
839
- self.observations.push(KernelObservation::BudgetExceeded {
840
- turn: self.turn,
841
- budget: "rounds".into(),
842
- operation_id: String::new(),
843
- reservation_id: self
844
- .budget_grant
845
- .as_ref()
846
- .map(|grant| grant.reservation_id.clone()),
847
- });
848
- self.pending_pace = Some(crate::types::result::PaceDecision {
849
- action: crate::types::result::PaceAction::Stop,
850
- delay_ms: None,
851
- reason: "round budget grant exhausted before start".into(),
852
- coerced_from: None,
853
- });
854
- return self.terminate(TerminationReason::Completed, None);
837
+ && self.budget_grant.as_ref().and_then(|grant| grant.rounds) == Some(0);
838
+ // A zero-token grant is the same exhausted admission on the token axis, but it binds
839
+ // every vehicle, loop or not. Both axes can race to zero on one reservation; report
840
+ // each before terminating so no provider call is ever dispatched.
841
+ let zero_token_grant = self.budget_grant.as_ref().and_then(|grant| grant.tokens) == Some(0);
842
+ if zero_round_grant || zero_token_grant {
843
+ if zero_round_grant {
844
+ self.observations.push(KernelObservation::BudgetExceeded {
845
+ turn: self.turn,
846
+ budget: "rounds".into(),
847
+ operation_id: String::new(),
848
+ reservation_id: self
849
+ .budget_grant
850
+ .as_ref()
851
+ .map(|grant| grant.reservation_id.clone()),
852
+ });
853
+ self.pending_pace = Some(crate::types::result::PaceDecision {
854
+ action: crate::types::result::PaceAction::Stop,
855
+ delay_ms: None,
856
+ reason: "round budget grant exhausted before start".into(),
857
+ coerced_from: None,
858
+ });
859
+ }
860
+ if zero_token_grant {
861
+ self.observations.push(KernelObservation::BudgetExceeded {
862
+ turn: self.turn,
863
+ budget: "tokens".into(),
864
+ operation_id: String::new(),
865
+ reservation_id: self
866
+ .budget_grant
867
+ .as_ref()
868
+ .map(|grant| grant.reservation_id.clone()),
869
+ });
870
+ }
871
+ // Token exhaustion is the harder stop: prefer it when both axes are zero.
872
+ return self.terminate(
873
+ if zero_token_grant {
874
+ TerminationReason::TokenBudget
875
+ } else {
876
+ TerminationReason::Completed
877
+ },
878
+ None,
879
+ );
855
880
  }
856
881
 
857
882
  let user_msg = "Proceed with the task described in [TASK STATE].".to_string();
@@ -4340,6 +4340,34 @@ fn zero_round_grant_stops_before_provider_dispatch() {
4340
4340
  )));
4341
4341
  }
4342
4342
 
4343
+ #[test]
4344
+ fn zero_token_grant_stops_before_provider_dispatch() {
4345
+ let mut sm = sm();
4346
+ sm.set_budget_grant(crate::runtime::kernel::BudgetGrant {
4347
+ reservation_id: "no-tokens".into(),
4348
+ tokens: Some(0),
4349
+ subagents: None,
4350
+ rounds: None,
4351
+ });
4352
+
4353
+ let action = sm.start(RuntimeTask::new("write"));
4354
+
4355
+ match action {
4356
+ LoopAction::Done { result } => {
4357
+ assert_eq!(result.termination, TerminationReason::TokenBudget);
4358
+ }
4359
+ other => panic!("expected Done, got {other:?}"),
4360
+ }
4361
+ assert_eq!(
4362
+ sm.turn, 0,
4363
+ "no provider turn may start without token capacity"
4364
+ );
4365
+ assert!(sm.take_observations().iter().any(|observation| matches!(
4366
+ observation,
4367
+ KernelObservation::BudgetExceeded { budget, .. } if budget == "tokens"
4368
+ )));
4369
+ }
4370
+
4343
4371
  #[test]
4344
4372
  fn pace_stop_routes_through_criteria_gate_then_honors_the_redecision() {
4345
4373
  let mut sm = loop_sm(crate::types::agent::LoopRoundSpec::default());
@@ -248,9 +248,11 @@ class LocalExecutionPlane:
248
248
  audit=_audit,
249
249
  )
250
250
  try:
251
- kwargs = json.loads(call.arguments or "{}")
252
- original_args_str = json.dumps(kwargs)
253
- validation = validate_tool_arguments(registered.schema.parameters, kwargs)
251
+ raw_kwargs = json.loads(call.arguments or "{}")
252
+ original_args_str = json.dumps(raw_kwargs)
253
+ # validation["args"], not raw_kwargs, from here on: a oneOf/anyOf ROOT accepts a repaired
254
+ # probe deep-copy — the original dict never sees those repairs (auto-casts, strips, defaults).
255
+ validation = validate_tool_arguments(registered.schema.parameters, raw_kwargs)
254
256
  if validation.get("error"):
255
257
  yield ToolResultEvent(
256
258
  call_id=call.id,
@@ -261,6 +263,7 @@ class LocalExecutionPlane:
261
263
  error_kind="recoverable",
262
264
  )
263
265
  return
266
+ kwargs = validation["args"]
264
267
  if validation.get("repaired"):
265
268
  yield ToolArgumentRepairedEvent(
266
269
  call_id=call.id,
@@ -278,6 +278,11 @@ class RuntimeOptions:
278
278
  # L1 (RunGroup): bind this runner to a governance domain shared by N peer sessions of one logical
279
279
  # run. The store must atomically reserve, settle, and release capacity. None ⇒ N=1.
280
280
  run_group: "RunGroup | None" = None
281
+ # Set by the SubAgentOrchestrator for host-derived child runs: the child still joins the
282
+ # `run_group` (lineage) and settles its actual terminal usage into the group ledger, but reserves
283
+ # no budget axes — group admission governs peer vehicles only. The child's caps stay local
284
+ # (kernel `max_total_tokens` policy + `resource_quota`). Never set this for a top-level run.
285
+ nested_group_vehicle: bool = False
281
286
  memory_policy: MemoryPolicy | dict[str, Any] | None = None
282
287
  os_profile: "OsProfile | None" = None
283
288
  tokenizer: str | None = None
@@ -747,6 +752,7 @@ class RuntimeRunner:
747
752
  spec=spec,
748
753
  manifest=manifest,
749
754
  session_log=self._opts.session_log,
755
+ tool_access=spec.tool_access or "filtered",
750
756
  harness=self._opts.sub_agent_harness,
751
757
  ))
752
758
 
@@ -2180,7 +2186,10 @@ class RuntimeRunner:
2180
2186
  # only local granted capacity and reports exact terminal usage against the same reservation id.
2181
2187
  group_budget_scope: GroupBudgetScope | None = None
2182
2188
  if self._opts.run_group is not None:
2183
- request = self._group_budget_request()
2189
+ # A nested vehicle (derived by the SubAgentOrchestrator) joins for lineage and settles actual
2190
+ # usage, but reserves no budget axes — group admission governs peer vehicles only; the
2191
+ # child's caps stay local (kernel policy + resource quota).
2192
+ request = ({}, {}) if self._opts.nested_group_vehicle else self._group_budget_request()
2184
2193
  group_budget_scope = await GroupBudgetScope.open(
2185
2194
  self._opts.run_group,
2186
2195
  GroupMember(session_id, self._opts.agent_id, kind="vehicle"),
@@ -2189,15 +2198,22 @@ class RuntimeRunner:
2189
2198
  )
2190
2199
  self._active_group_budget_scope = group_budget_scope
2191
2200
  granted = group_budget_scope.granted
2192
- kernel_apply(runtime, self._pending_observations, {
2193
- "kind": "configure_run",
2194
- "config": {"budget_grant": {
2195
- "reservation_id": group_budget_scope.reservation_id,
2196
- **({"tokens": granted.tokens} if granted.tokens is not None else {}),
2197
- **({"subagents": granted.subagents} if granted.subagents is not None else {}),
2198
- **({"rounds": granted.rounds} if granted.rounds is not None else {}),
2199
- }},
2200
- })
2201
+ try:
2202
+ kernel_apply(runtime, self._pending_observations, {
2203
+ "kind": "configure_run",
2204
+ "config": {"budget_grant": {
2205
+ "reservation_id": group_budget_scope.reservation_id,
2206
+ **({"tokens": granted.tokens} if granted.tokens is not None else {}),
2207
+ **({"subagents": granted.subagents} if granted.subagents is not None else {}),
2208
+ **({"rounds": granted.rounds} if granted.rounds is not None else {}),
2209
+ }},
2210
+ })
2211
+ except Exception:
2212
+ # Admission failure (e.g. the kernel rejecting a zero-capacity grant): release the
2213
+ # reservation so it cannot linger in the group ledger, then surface the error.
2214
+ await group_budget_scope.release()
2215
+ self._active_group_budget_scope = None
2216
+ raise
2201
2217
 
2202
2218
  if self._opts.memory_policy is not None:
2203
2219
  kernel_apply(runtime, self._pending_observations, {
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import warnings
3
4
  from dataclasses import dataclass, replace
4
5
  from typing import TYPE_CHECKING, Any
5
6
 
@@ -141,6 +142,19 @@ def _resolve_tool_grants(ctx: SubAgentRunContext) -> tuple[Any, frozenset[str]]:
141
142
  return plane, _available_meta_tools(ctx.parent_opts)
142
143
  permitted = set(ctx.manifest.permitted_capability_ids)
143
144
  meta_tools = _derive_meta_tools(permitted, ctx.parent_opts)
145
+ # A "filtered" spawn with no capability grants and no meta-tools resolves to a deny-all plane —
146
+ # the child model sees zero tools and reports "no tools available". Warn the host (visible, not
147
+ # fatal) with the fix, mirroring execution_plane's failure-shaped-chunk warning. Exempt workflow
148
+ # nodes: not-inherit + workflow-node ⇒ quarantined ⇒ intentional deny-all, not a misconfiguration.
149
+ if not ctx.is_workflow_node and not permitted and not meta_tools:
150
+ warnings.warn(
151
+ f'spawned sub-agent "{ctx.spec.identity.agent_id}" resolved to zero tools (deny-all filter). '
152
+ "Mount tools as capabilities and grant via spec.capability_filter, or pass "
153
+ "spec.tool_access='inherit' to run on the parent's plane. If a tool-less child is intentional, "
154
+ "ignore this.",
155
+ RuntimeWarning,
156
+ stacklevel=2,
157
+ )
144
158
  return FilteredExecutionPlane(plane, permitted, meta_tools), meta_tools
145
159
 
146
160
 
@@ -200,6 +214,10 @@ def _build_child_opts(
200
214
  enable_plan_tool=ctx.parent_opts.enable_plan_tool if "update_plan" in meta_tools else None,
201
215
  # M5 v2.1: a workflow node's `start_workflow` flattens to the parent kernel (no nested pivot).
202
216
  is_workflow_node=ctx.is_workflow_node,
217
+ # Nested vehicle: the child joins the inherited run_group for lineage/settlement only — it
218
+ # must NOT re-reserve budget axes the parent already holds (that double-reserve squeezed the
219
+ # child's grant to 0 and the kernel stripped its first-turn tools).
220
+ nested_group_vehicle=True,
203
221
  # The child runs under ITS OWN spec, never the parent's: the replace() above would otherwise
204
222
  # leak the parent's ``run_spec`` (identity, capability filter — and a LoopDriver's armed
205
223
  # ``loop_round``, giving every child a phantom pace tool). A loop-node iteration carries its
@@ -22,7 +22,9 @@ async def execute_tools(
22
22
  if validation.get("error"):
23
23
  results.append(ToolResult(call_id=call.id, output=f"invalid arguments: {validation['error']}", is_error=True))
24
24
  continue
25
- output = await tool(**kwargs)
25
+ # validation["args"], not kwargs: a oneOf/anyOf ROOT accepts a repaired probe
26
+ # deep-copy — the original dict never sees those repairs (auto-casts, strips, defaults).
27
+ output = await tool(**validation["args"])
26
28
  if isinstance(output, AsyncIterable):
27
29
  chunks = []
28
30
  async for chunk in output:
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
  import copy
3
3
  import inspect
4
4
  import json
5
+ import re
5
6
  from collections.abc import AsyncIterable
6
7
  from typing import Any, Callable
7
8
  from deepstrike._kernel import ToolSchema
@@ -73,11 +74,13 @@ def validate_tool_arguments(schema_json: str, args: dict[str, Any]) -> dict[str,
73
74
  try:
74
75
  schema = json.loads(schema_json)
75
76
  except Exception:
76
- return {"error": "invalid tool schema", "repaired": False}
77
+ return {"error": "invalid tool schema", "repaired": False, "args": args}
77
78
  state = {"repaired": False}
78
79
  wrapper = {"root": args}
79
80
  error = _validate_value(schema, wrapper, "root", "$", state)
80
- return {"error": error, "repaired": state["repaired"]}
81
+ # A oneOf/anyOf ROOT replaces the value with its accepted probe deep-copy — in-place mutation
82
+ # of the caller's dict only covers non-union roots. Callers must use the returned "args".
83
+ return {"error": error, "repaired": state["repaired"], "args": wrapper["root"]}
81
84
 
82
85
 
83
86
  def _validate_value(schema: dict[str, Any], parent: Any, key: Any, path: str, state: dict[str, bool]) -> str | None:
@@ -200,10 +203,65 @@ def _validate_value(schema: dict[str, Any], parent: Any, key: Any, path: str, st
200
203
  return f"{path} must be integer"
201
204
  elif expected == "boolean" and not isinstance(value, bool):
202
205
  return f"{path} must be boolean"
206
+ elif expected == "null" and value is not None:
207
+ return f"{path} must be null"
203
208
  elif path == "$" and not isinstance(value, dict):
204
209
  return f"{path} must be object"
205
210
 
206
211
  enum_values = schema.get("enum")
207
212
  if enum_values is not None and value not in enum_values:
208
213
  return f"{path} must be one of enum values"
214
+ # `const` is THE discriminator convention for oneOf variants (kind: {const: "edit"}). Without
215
+ # it, union branches match on required+type alone and the WRONG branch can win — then its
216
+ # allow-list strips keys the right branch declared.
217
+ if "const" in schema:
218
+ want = schema["const"]
219
+ if isinstance(want, bool) or isinstance(value, bool):
220
+ matches = value is want
221
+ else:
222
+ matches = value == want
223
+ if not matches:
224
+ return f"{path} must equal the const value {json.dumps(want)}"
225
+ # Constraint keywords, checked per the value's actual type (JSON Schema semantics: string
226
+ # constraints ignore non-strings, etc.). Keywords outside this set (allOf, multipleOf,
227
+ # uniqueItems, format, if/then/else, …) are ignored, not rejected.
228
+ if isinstance(value, str):
229
+ min_length = schema.get("minLength")
230
+ if isinstance(min_length, int) and len(value) < min_length:
231
+ return f"{path} must be at least {min_length} characters"
232
+ max_length = schema.get("maxLength")
233
+ if isinstance(max_length, int) and len(value) > max_length:
234
+ return f"{path} must be at most {max_length} characters"
235
+ pattern = schema.get("pattern")
236
+ if isinstance(pattern, str):
237
+ try:
238
+ compiled = re.compile(pattern)
239
+ except re.error:
240
+ compiled = None # author-side bad regex: skip, never fail the call
241
+ if compiled is not None and compiled.search(value) is None:
242
+ return f"{path} must match pattern {pattern}"
243
+ elif isinstance(value, (int, float)) and not isinstance(value, bool):
244
+ for keyword, ok in (
245
+ ("minimum", lambda bound: value >= bound),
246
+ ("maximum", lambda bound: value <= bound),
247
+ ("exclusiveMinimum", lambda bound: value > bound),
248
+ ("exclusiveMaximum", lambda bound: value < bound),
249
+ ):
250
+ bound = schema.get(keyword)
251
+ if isinstance(bound, (int, float)) and not isinstance(bound, bool) and not ok(bound):
252
+ op = {"minimum": ">=", "maximum": "<=", "exclusiveMinimum": ">", "exclusiveMaximum": "<"}[keyword]
253
+ return f"{path} must be {op} {bound}"
254
+ elif isinstance(value, list):
255
+ min_items = schema.get("minItems")
256
+ if isinstance(min_items, int) and len(value) < min_items:
257
+ return f"{path} must have at least {min_items} items"
258
+ max_items = schema.get("maxItems")
259
+ if isinstance(max_items, int) and len(value) > max_items:
260
+ return f"{path} must have at most {max_items} items"
261
+ # `not`: probe on a deep copy so a matching (= rejected) subschema's repairs never leak out.
262
+ not_schema = schema.get("not")
263
+ if isinstance(not_schema, dict):
264
+ probe = {"v": copy.deepcopy(value)}
265
+ if _validate_value(not_schema, probe, "v", path, {"repaired": False}) is None:
266
+ return f"{path} must not match the disallowed shape"
209
267
  return None
@@ -81,6 +81,13 @@ class AgentRunSpec:
81
81
  # dict: {"max_rounds"?, "min_sleep_ms"?, "max_sleep_ms"?, "default_action"?}. Only set keys are
82
82
  # lowered to the kernel; None ⇒ no trap (a plain run).
83
83
  loop_round: dict[str, Any] | None = None
84
+ # Tool surface for a spawned sub-agent. Host-side only (like ``model_hint``) — NOT sent to the
85
+ # kernel (``agent_run_spec_to_kernel`` maps fields explicitly and omits it). Default "filtered"
86
+ # keeps the spawn path's deny-all-safe default: the child is filtered to its manifest grants, and a
87
+ # grant-less spawn resolves to zero tools. "inherit" runs the child on the parent's execution plane
88
+ # with the parent's meta-tool availability (same mechanism trusted workflow nodes use) — the child's
89
+ # surface is a subset of the parent's, never a privilege escalation.
90
+ tool_access: str = "filtered" # "inherit" | "filtered"
84
91
 
85
92
 
86
93
  @dataclass
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "deepstrike"
7
- version = "0.2.44"
7
+ version = "0.2.46"
8
8
  requires-python = ">=3.10"
9
9
  readme = "README.md"
10
10
  dependencies = [
File without changes