deepstrike 0.2.27__tar.gz → 0.2.30__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.
- {deepstrike-0.2.27 → deepstrike-0.2.30}/Cargo.lock +5 -5
- {deepstrike-0.2.27 → deepstrike-0.2.30}/Cargo.toml +2 -2
- {deepstrike-0.2.27 → deepstrike-0.2.30}/PKG-INFO +39 -12
- {deepstrike-0.2.27 → deepstrike-0.2.30}/README.md +38 -11
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/runtime/kernel.rs +281 -41
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/scheduler/state_machine/workflow.rs +17 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/__init__.py +5 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/providers/__init__.py +5 -3
- deepstrike-0.2.30/deepstrike/providers/factories.py +80 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/__init__.py +3 -0
- deepstrike-0.2.30/deepstrike/runtime/facade.py +89 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/runner.py +80 -9
- {deepstrike-0.2.27 → deepstrike-0.2.30}/pyproject.toml +1 -1
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/Cargo.toml +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/context/compression.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/context/config.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/context/dashboard.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/context/manager.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/context/mod.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/context/partitions.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/context/pressure.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/context/renderer.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/context/renewal.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/context/sections.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/context/skill_catalog.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/context/snapshot.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/context/summarizer.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/context/task_state.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/context/text.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/context/token_engine.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/governance/audit.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/governance/constraint.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/governance/mod.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/governance/permission.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/governance/pipeline.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/governance/quota.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/governance/rate_limit.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/governance/sandbox.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/governance/tool_decision.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/governance/veto.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/harness/eval.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/harness/mod.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/lib.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/memory/curator.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/memory/durable.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/memory/extractor.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/memory/idle_pipeline.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/memory/mod.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/memory/runtime.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/memory/semantic.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/memory/session.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/memory/synthesis.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/memory/trace_analyzer.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/memory/working.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/mm/handle.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/mm/memory.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/mm/mod.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/orchestration/mod.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/orchestration/task_graph.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/orchestration/tournament.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/orchestration/workflow/mod.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/orchestration/workflow/run.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/proc/mod.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/runtime/event_log.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/runtime/mod.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/runtime/repair.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/runtime/replay.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/runtime/session.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/runtime/snapshot.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/scheduler/milestone.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/scheduler/mod.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/scheduler/policy.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/scheduler/rollback.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/scheduler/state_machine/capability.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/scheduler/state_machine/eviction.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/scheduler/state_machine/gate.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/scheduler/state_machine/milestone_exec.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/scheduler/state_machine/mod.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/scheduler/state_machine/process.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/scheduler/state_machine/signal.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/scheduler/state_machine/tests.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/scheduler/tcb.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/signals/attention.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/signals/mod.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/signals/queue.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/signals/router.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/syscall/mod.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/types/agent.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/types/capability.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/types/contract.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/types/error.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/types/message.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/types/milestone.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/types/mod.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/types/model.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/types/policy.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/types/result.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/types/signal.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/types/skill.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-core/src/types/task.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-py/Cargo.toml +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/crates/deepstrike-py/src/lib.rs +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/collaboration/__init__.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/collaboration/contract.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/collaboration/handoff.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/collaboration/harness.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/collaboration/modes.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/collaboration/pool.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/governance.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/harness/__init__.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/harness/harness.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/kernel/__init__.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/knowledge/__init__.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/knowledge/source.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/memory/__init__.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/memory/agent.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/memory/in_memory_store.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/memory/protocols.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/memory/working.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/providers/anthropic.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/providers/base.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/providers/deepseek.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/providers/gemini.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/providers/glm.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/providers/kimi.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/providers/minimax.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/providers/ollama.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/providers/openai.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/providers/openai_responses.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/providers/qwen.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/providers/replay.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/providers/replay_validator.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/providers/stream.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/archive.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/credential_vault.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/eval.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/execution_plane.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/filtered_plane.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/kernel_event_log.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/kernel_step.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/large_result_spool.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/mcp_proxy_plane.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/os_profile.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/os_snapshot.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/output_schema.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/process_sandbox_plane.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/provider_replay.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/reducers.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/remote_vpc_plane.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/replay_fixture.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/replay_provider.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/replay_sanitize.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/session_log.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/session_repair.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/sub_agent_orchestrator.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/workflow_control_flow.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/workflow_store.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/runtime/worktree_plane.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/safety/__init__.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/safety/permissions.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/signals/__init__.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/signals/gateway.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/signals/scheduled.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/signals/types.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/skills/__init__.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/skills/registry.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/skills/watcher.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/tools/__init__.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/tools/builtin/__init__.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/tools/builtin/read_file.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/tools/errors.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/tools/execution.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/tools/registry.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/types/__init__.py +0 -0
- {deepstrike-0.2.27 → deepstrike-0.2.30}/deepstrike/types/agent.py +0 -0
|
@@ -194,7 +194,7 @@ dependencies = [
|
|
|
194
194
|
|
|
195
195
|
[[package]]
|
|
196
196
|
name = "deepstrike-core"
|
|
197
|
-
version = "0.2.
|
|
197
|
+
version = "0.2.30"
|
|
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-node"
|
|
209
|
-
version = "0.2.
|
|
209
|
+
version = "0.2.30"
|
|
210
210
|
dependencies = [
|
|
211
211
|
"compact_str",
|
|
212
212
|
"deepstrike-core",
|
|
@@ -218,7 +218,7 @@ dependencies = [
|
|
|
218
218
|
|
|
219
219
|
[[package]]
|
|
220
220
|
name = "deepstrike-py"
|
|
221
|
-
version = "0.2.
|
|
221
|
+
version = "0.2.30"
|
|
222
222
|
dependencies = [
|
|
223
223
|
"compact_str",
|
|
224
224
|
"deepstrike-core",
|
|
@@ -229,7 +229,7 @@ dependencies = [
|
|
|
229
229
|
|
|
230
230
|
[[package]]
|
|
231
231
|
name = "deepstrike-sdk"
|
|
232
|
-
version = "0.2.
|
|
232
|
+
version = "0.2.30"
|
|
233
233
|
dependencies = [
|
|
234
234
|
"async-stream",
|
|
235
235
|
"async-trait",
|
|
@@ -263,7 +263,7 @@ dependencies = [
|
|
|
263
263
|
|
|
264
264
|
[[package]]
|
|
265
265
|
name = "deepstrike-wasm"
|
|
266
|
-
version = "0.2.
|
|
266
|
+
version = "0.2.30"
|
|
267
267
|
dependencies = [
|
|
268
268
|
"compact_str",
|
|
269
269
|
"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.
|
|
6
|
+
version = "0.2.30"
|
|
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.
|
|
12
|
+
deepstrike-core = { path = "crates/deepstrike-core", version = "0.2.30" }
|
|
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.
|
|
3
|
+
Version: 0.2.30
|
|
4
4
|
Requires-Dist: httpx>=0.27
|
|
5
5
|
Requires-Dist: pyyaml>=6.0
|
|
6
6
|
Requires-Dist: anyio>=4.0
|
|
@@ -68,6 +68,25 @@ asyncio.run(collect_text(runner.run(
|
|
|
68
68
|
# => "45"
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
+
### Recipes — the canonical entry points
|
|
72
|
+
|
|
73
|
+
Most apps need one of two shapes. Start with the facades; drop to `RuntimeRunner` for streaming, tools, signals, memory, or governance.
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from deepstrike import run_agent, run_fanout
|
|
77
|
+
|
|
78
|
+
# 1) Single agent — one prompt, one model, the text back.
|
|
79
|
+
answer = await run_agent(provider=provider, goal="What is 17 + 28?", tools=[add])
|
|
80
|
+
|
|
81
|
+
# 2) Parallel fan-out → synthesize over the kernel-gated DAG (safe from a stateless handler).
|
|
82
|
+
out = await run_fanout(
|
|
83
|
+
provider=provider,
|
|
84
|
+
tasks=["Summarize the auth module", "Summarize the data layer"],
|
|
85
|
+
synthesize="Combine the findings into one summary.",
|
|
86
|
+
)
|
|
87
|
+
synthesis = out["synthesis"]
|
|
88
|
+
```
|
|
89
|
+
|
|
71
90
|
Same-session continuity is explicit via `session_id`:
|
|
72
91
|
|
|
73
92
|
```python
|
|
@@ -205,17 +224,25 @@ runner = RuntimeRunner(RuntimeOptions(
|
|
|
205
224
|
))
|
|
206
225
|
```
|
|
207
226
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
227
|
+
The top-level package exports the base providers `OpenAIProvider`, `OpenAIResponsesProvider`, and
|
|
228
|
+
`AnthropicProvider`. **Every other backend is a factory function** in `deepstrike.providers`, with a
|
|
229
|
+
`protocol` argument where a backend speaks both the OpenAI- and Anthropic-compatible wire:
|
|
230
|
+
|
|
231
|
+
```python
|
|
232
|
+
from deepstrike.providers import deepseek, kimi, minimax
|
|
233
|
+
|
|
234
|
+
ds = deepseek(api_key="...") # OpenAI-compatible wire (default)
|
|
235
|
+
dsA = deepseek(api_key="...", protocol="anthropic") # Anthropic-compatible wire
|
|
236
|
+
mm = minimax(api_key="...") # MiniMax defaults to the Anthropic wire
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
| Entry | Import from | Backend |
|
|
240
|
+
|-------|-------------|---------|
|
|
241
|
+
| `OpenAIProvider` / `OpenAIResponsesProvider` | `deepstrike` | OpenAI (and OpenAI-compatible) |
|
|
242
|
+
| `AnthropicProvider` | `deepstrike` | Anthropic Messages API |
|
|
243
|
+
| `deepseek` · `kimi` · `qwen` · `glm` · `minimax` · `gemini` · `ollama` | `deepstrike.providers` | the respective vendor (factory functions) |
|
|
244
|
+
|
|
245
|
+
All providers accept `retry_config` for exponential backoff and share a `CircuitBreaker`.
|
|
219
246
|
|
|
220
247
|
`extensions` are forwarded to the provider while SDK-owned structural fields remain protected.
|
|
221
248
|
|
|
@@ -55,6 +55,25 @@ asyncio.run(collect_text(runner.run(
|
|
|
55
55
|
# => "45"
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
+
### Recipes — the canonical entry points
|
|
59
|
+
|
|
60
|
+
Most apps need one of two shapes. Start with the facades; drop to `RuntimeRunner` for streaming, tools, signals, memory, or governance.
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from deepstrike import run_agent, run_fanout
|
|
64
|
+
|
|
65
|
+
# 1) Single agent — one prompt, one model, the text back.
|
|
66
|
+
answer = await run_agent(provider=provider, goal="What is 17 + 28?", tools=[add])
|
|
67
|
+
|
|
68
|
+
# 2) Parallel fan-out → synthesize over the kernel-gated DAG (safe from a stateless handler).
|
|
69
|
+
out = await run_fanout(
|
|
70
|
+
provider=provider,
|
|
71
|
+
tasks=["Summarize the auth module", "Summarize the data layer"],
|
|
72
|
+
synthesize="Combine the findings into one summary.",
|
|
73
|
+
)
|
|
74
|
+
synthesis = out["synthesis"]
|
|
75
|
+
```
|
|
76
|
+
|
|
58
77
|
Same-session continuity is explicit via `session_id`:
|
|
59
78
|
|
|
60
79
|
```python
|
|
@@ -192,17 +211,25 @@ runner = RuntimeRunner(RuntimeOptions(
|
|
|
192
211
|
))
|
|
193
212
|
```
|
|
194
213
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
214
|
+
The top-level package exports the base providers `OpenAIProvider`, `OpenAIResponsesProvider`, and
|
|
215
|
+
`AnthropicProvider`. **Every other backend is a factory function** in `deepstrike.providers`, with a
|
|
216
|
+
`protocol` argument where a backend speaks both the OpenAI- and Anthropic-compatible wire:
|
|
217
|
+
|
|
218
|
+
```python
|
|
219
|
+
from deepstrike.providers import deepseek, kimi, minimax
|
|
220
|
+
|
|
221
|
+
ds = deepseek(api_key="...") # OpenAI-compatible wire (default)
|
|
222
|
+
dsA = deepseek(api_key="...", protocol="anthropic") # Anthropic-compatible wire
|
|
223
|
+
mm = minimax(api_key="...") # MiniMax defaults to the Anthropic wire
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
| Entry | Import from | Backend |
|
|
227
|
+
|-------|-------------|---------|
|
|
228
|
+
| `OpenAIProvider` / `OpenAIResponsesProvider` | `deepstrike` | OpenAI (and OpenAI-compatible) |
|
|
229
|
+
| `AnthropicProvider` | `deepstrike` | Anthropic Messages API |
|
|
230
|
+
| `deepseek` · `kimi` · `qwen` · `glm` · `minimax` · `gemini` · `ollama` | `deepstrike.providers` | the respective vendor (factory functions) |
|
|
231
|
+
|
|
232
|
+
All providers accept `retry_config` for exponential backoff and share a `CircuitBreaker`.
|
|
206
233
|
|
|
207
234
|
`extensions` are forwarded to the provider while SDK-owned structural fields remain protected.
|
|
208
235
|
|
|
@@ -106,6 +106,102 @@ impl KernelInput {
|
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
/// K2: the governance sub-bundle of [`RunConfig`] — the same five fields as the `LoadGovernancePolicy`
|
|
110
|
+
/// event, grouped so a run's whole governance posture travels as one value.
|
|
111
|
+
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
|
112
|
+
pub struct GovernanceConfig {
|
|
113
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
114
|
+
pub default_action: Option<PolicyAction>,
|
|
115
|
+
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
|
116
|
+
pub rules: Vec<PolicyRule>,
|
|
117
|
+
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
|
118
|
+
pub vetoed_tools: Vec<String>,
|
|
119
|
+
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
|
120
|
+
pub rate_limits: Vec<RateLimitSpec>,
|
|
121
|
+
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
|
122
|
+
pub constraints: Vec<ConstraintSpec>,
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/// K2: a bundle of run-setup configuration carried by the [`KernelInputEvent::ConfigureRun`] event.
|
|
126
|
+
/// Each field maps 1:1 to a granular `Set*` / `Load*` event; `None`/absent leaves that aspect untouched.
|
|
127
|
+
/// This is the host-side analogue of the SDK's `applyKernelPolicies` — one event for the whole setup.
|
|
128
|
+
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
|
129
|
+
pub struct RunConfig {
|
|
130
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
131
|
+
pub tools: Option<Vec<ToolSchema>>,
|
|
132
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
133
|
+
pub available_skills: Option<Vec<SkillMetadata>>,
|
|
134
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
135
|
+
pub stable_core_tools: Option<Vec<String>>,
|
|
136
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
137
|
+
pub memory_enabled: Option<bool>,
|
|
138
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
139
|
+
pub knowledge_enabled: Option<bool>,
|
|
140
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
141
|
+
pub plan_tool_enabled: Option<bool>,
|
|
142
|
+
/// Present (any value) ⇒ reset the token engine to the char-approx estimator (see `SetTokenizer`).
|
|
143
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
144
|
+
pub tokenizer: Option<String>,
|
|
145
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
146
|
+
pub governance: Option<GovernanceConfig>,
|
|
147
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
148
|
+
pub attention_max_queue_size: Option<u32>,
|
|
149
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
150
|
+
pub scheduler_max_wall_ms: Option<u64>,
|
|
151
|
+
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
152
|
+
pub resource_quota: Option<crate::governance::quota::ResourceQuota>,
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/// Build a [`GovernancePipeline`](crate::governance::pipeline::GovernancePipeline) from the ABI policy
|
|
156
|
+
/// fields. Shared by the `LoadGovernancePolicy` event and the `ConfigureRun` bundle so the two can never
|
|
157
|
+
/// drift in how they interpret rules / vetoes / rate-limits / constraints.
|
|
158
|
+
pub(crate) fn build_governance_pipeline(
|
|
159
|
+
default_action: Option<PolicyAction>,
|
|
160
|
+
rules: Vec<PolicyRule>,
|
|
161
|
+
vetoed_tools: Vec<String>,
|
|
162
|
+
rate_limits: Vec<RateLimitSpec>,
|
|
163
|
+
constraints: Vec<ConstraintSpec>,
|
|
164
|
+
) -> crate::governance::pipeline::GovernancePipeline {
|
|
165
|
+
use crate::governance::constraint::{ConstraintRule, ParamConstraint};
|
|
166
|
+
use crate::governance::permission::PermissionRule;
|
|
167
|
+
use crate::governance::rate_limit::RateLimit;
|
|
168
|
+
let default = default_action.unwrap_or(PolicyAction::Allow).into();
|
|
169
|
+
let mut pipeline = crate::governance::pipeline::GovernancePipeline::new(default);
|
|
170
|
+
for rule in rules {
|
|
171
|
+
pipeline.permission.add_rule(PermissionRule {
|
|
172
|
+
tool_pattern: rule.tool_pattern.into(),
|
|
173
|
+
action: rule.action.into(),
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
for tool in vetoed_tools {
|
|
177
|
+
pipeline.veto.block_tool(tool);
|
|
178
|
+
}
|
|
179
|
+
for rl in rate_limits {
|
|
180
|
+
pipeline.rate_limiter.set_limit(
|
|
181
|
+
rl.tool,
|
|
182
|
+
RateLimit {
|
|
183
|
+
max_calls: rl.max_calls,
|
|
184
|
+
window_ms: rl.window_ms,
|
|
185
|
+
},
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
for c in constraints {
|
|
189
|
+
let (tool_name, param_path, rule) = match c {
|
|
190
|
+
ConstraintSpec::Required { tool, path } => (tool, path, ConstraintRule::Required),
|
|
191
|
+
ConstraintSpec::Enum { tool, path, values } => (tool, path, ConstraintRule::Enum(values)),
|
|
192
|
+
ConstraintSpec::Range { tool, path, min, max } => {
|
|
193
|
+
(tool, path, ConstraintRule::Range { min, max })
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
pipeline.constraints.add(ParamConstraint {
|
|
197
|
+
tool_name,
|
|
198
|
+
param_path,
|
|
199
|
+
rule,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
pipeline
|
|
203
|
+
}
|
|
204
|
+
|
|
109
205
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
110
206
|
#[serde(tag = "kind", rename_all = "snake_case")]
|
|
111
207
|
pub enum KernelInputEvent {
|
|
@@ -195,6 +291,13 @@ pub enum KernelInputEvent {
|
|
|
195
291
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
196
292
|
run_spec: Option<AgentRunSpec>,
|
|
197
293
|
},
|
|
294
|
+
/// K2: apply a bundle of run-setup configuration in a single event — the consolidation of the
|
|
295
|
+
/// ~10 discrete `Set*` / `Load*` config events the SDK used to fire one-by-one before `StartRun`.
|
|
296
|
+
/// Every field is optional; an absent field leaves that aspect untouched. The granular events
|
|
297
|
+
/// remain for runtime mutation (a skill mount changing tools, a mid-run budget change). ABI-additive.
|
|
298
|
+
ConfigureRun {
|
|
299
|
+
config: RunConfig,
|
|
300
|
+
},
|
|
198
301
|
CapabilityCommand {
|
|
199
302
|
command: CapabilityCommand,
|
|
200
303
|
},
|
|
@@ -753,51 +856,74 @@ impl KernelRuntime {
|
|
|
753
856
|
rate_limits,
|
|
754
857
|
constraints,
|
|
755
858
|
} => {
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
859
|
+
self.sm.set_governance(build_governance_pipeline(
|
|
860
|
+
default_action,
|
|
861
|
+
rules,
|
|
862
|
+
vetoed_tools,
|
|
863
|
+
rate_limits,
|
|
864
|
+
constraints,
|
|
865
|
+
));
|
|
866
|
+
return KernelStep::empty(self.sm.take_observations());
|
|
867
|
+
}
|
|
868
|
+
KernelInputEvent::ConfigureRun { config } => {
|
|
869
|
+
// K2: apply a bundle of run-setup config in one event (tools / governance / attention /
|
|
870
|
+
// quota / scheduler / toggles), replacing the ~10 separate `Set*` / `Load*` events the
|
|
871
|
+
// SDK used to fire one-by-one. Each field is optional; an absent field is left untouched.
|
|
872
|
+
// The individual events remain for runtime mutation (skill mount, mid-run budget change).
|
|
873
|
+
// Each branch delegates to exactly the method its granular event uses, so the two paths
|
|
874
|
+
// can never diverge.
|
|
875
|
+
let RunConfig {
|
|
876
|
+
tools,
|
|
877
|
+
available_skills,
|
|
878
|
+
stable_core_tools,
|
|
879
|
+
memory_enabled,
|
|
880
|
+
knowledge_enabled,
|
|
881
|
+
plan_tool_enabled,
|
|
882
|
+
tokenizer,
|
|
883
|
+
governance,
|
|
884
|
+
attention_max_queue_size,
|
|
885
|
+
scheduler_max_wall_ms,
|
|
886
|
+
resource_quota,
|
|
887
|
+
} = config;
|
|
888
|
+
if let Some(tools) = tools {
|
|
889
|
+
self.sm.tools = tools;
|
|
766
890
|
}
|
|
767
|
-
|
|
768
|
-
|
|
891
|
+
if let Some(skills) = available_skills {
|
|
892
|
+
self.sm.ctx.set_available_skills(skills);
|
|
769
893
|
}
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
rl.tool,
|
|
773
|
-
RateLimit {
|
|
774
|
-
max_calls: rl.max_calls,
|
|
775
|
-
window_ms: rl.window_ms,
|
|
776
|
-
},
|
|
777
|
-
);
|
|
894
|
+
if let Some(ids) = stable_core_tools {
|
|
895
|
+
self.sm.ctx.set_stable_core_tools(ids.into_iter().map(Into::into));
|
|
778
896
|
}
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
897
|
+
if let Some(enabled) = memory_enabled {
|
|
898
|
+
self.sm.ctx.set_memory_enabled(enabled);
|
|
899
|
+
}
|
|
900
|
+
if let Some(enabled) = knowledge_enabled {
|
|
901
|
+
self.sm.ctx.set_knowledge_enabled(enabled);
|
|
902
|
+
}
|
|
903
|
+
if let Some(enabled) = plan_tool_enabled {
|
|
904
|
+
self.sm.ctx.set_plan_tool_enabled(enabled);
|
|
905
|
+
}
|
|
906
|
+
if tokenizer.is_some() {
|
|
907
|
+
self.sm.ctx.engine = ContextTokenEngine::char_approx();
|
|
908
|
+
}
|
|
909
|
+
if let Some(g) = governance {
|
|
910
|
+
self.sm.set_governance(build_governance_pipeline(
|
|
911
|
+
g.default_action,
|
|
912
|
+
g.rules,
|
|
913
|
+
g.vetoed_tools,
|
|
914
|
+
g.rate_limits,
|
|
915
|
+
g.constraints,
|
|
916
|
+
));
|
|
917
|
+
}
|
|
918
|
+
if let Some(max_queue) = attention_max_queue_size {
|
|
919
|
+
self.sm.set_attention(max_queue as usize);
|
|
920
|
+
}
|
|
921
|
+
if let Some(ms) = scheduler_max_wall_ms {
|
|
922
|
+
self.sm.set_wall_budget(Some(ms));
|
|
923
|
+
}
|
|
924
|
+
if let Some(quota) = resource_quota {
|
|
925
|
+
self.sm.set_resource_quota(quota);
|
|
799
926
|
}
|
|
800
|
-
self.sm.set_governance(pipeline);
|
|
801
927
|
return KernelStep::empty(self.sm.take_observations());
|
|
802
928
|
}
|
|
803
929
|
KernelInputEvent::SetAttentionPolicy { max_queue_size } => {
|
|
@@ -883,6 +1009,10 @@ impl KernelRuntime {
|
|
|
883
1009
|
resumed_completed,
|
|
884
1010
|
resumed_submissions,
|
|
885
1011
|
} => {
|
|
1012
|
+
// K1: self-bootstrap the run if the host never fired `StartRun` (stateless
|
|
1013
|
+
// `runWorkflow` caller). Parity with the agent-reachable `SubmitWorkflow`, which already
|
|
1014
|
+
// bootstraps. Idempotent no-op once the root task has left `Ready`.
|
|
1015
|
+
self.sm.ensure_started_for_workflow(&spec);
|
|
886
1016
|
let action = if resumed_completed.is_empty() && resumed_submissions.is_empty() {
|
|
887
1017
|
self.sm.load_workflow(spec, &parent_session_id)
|
|
888
1018
|
} else {
|
|
@@ -1542,6 +1672,62 @@ mod tests {
|
|
|
1542
1672
|
);
|
|
1543
1673
|
}
|
|
1544
1674
|
|
|
1675
|
+
#[test]
|
|
1676
|
+
fn configure_run_bundle_applies_governance_equivalently_to_load_governance_policy() {
|
|
1677
|
+
// K2: the consolidated `ConfigureRun` bundle must apply governance identically to the granular
|
|
1678
|
+
// `LoadGovernancePolicy` event — a deny rule blocks the matching tool and re-prompts.
|
|
1679
|
+
let mut runtime = KernelRuntime::new(LoopPolicy::default());
|
|
1680
|
+
runtime.step(KernelInput::new(KernelInputEvent::ConfigureRun {
|
|
1681
|
+
config: RunConfig {
|
|
1682
|
+
tools: Some(vec![]),
|
|
1683
|
+
governance: Some(GovernanceConfig {
|
|
1684
|
+
default_action: Some(PolicyAction::Allow),
|
|
1685
|
+
rules: vec![PolicyRule {
|
|
1686
|
+
tool_pattern: "danger.*".to_string(),
|
|
1687
|
+
action: PolicyAction::Deny,
|
|
1688
|
+
}],
|
|
1689
|
+
..GovernanceConfig::default()
|
|
1690
|
+
}),
|
|
1691
|
+
attention_max_queue_size: Some(32),
|
|
1692
|
+
..RunConfig::default()
|
|
1693
|
+
},
|
|
1694
|
+
}));
|
|
1695
|
+
|
|
1696
|
+
let step = run_with_tool_call(&mut runtime, "danger.delete");
|
|
1697
|
+
|
|
1698
|
+
assert!(
|
|
1699
|
+
matches!(step.actions.as_slice(), [KernelAction::CallProvider { .. }]),
|
|
1700
|
+
"bundle-configured deny should roll back and re-call provider, got {:?}",
|
|
1701
|
+
step.actions
|
|
1702
|
+
);
|
|
1703
|
+
assert!(
|
|
1704
|
+
step.observations
|
|
1705
|
+
.iter()
|
|
1706
|
+
.any(|o| matches!(o, KernelObservation::Rollbacked { .. })),
|
|
1707
|
+
"expected a Rollbacked observation for the bundle-denied turn",
|
|
1708
|
+
);
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
#[test]
|
|
1712
|
+
fn configure_run_round_trips_over_the_abi() {
|
|
1713
|
+
// The bundle must survive the versioned JSON ABI (replayable / session-loggable) like every
|
|
1714
|
+
// other host event.
|
|
1715
|
+
let event = KernelInputEvent::ConfigureRun {
|
|
1716
|
+
config: RunConfig {
|
|
1717
|
+
resource_quota: Some(crate::governance::quota::ResourceQuota {
|
|
1718
|
+
max_concurrent_subagents: Some(2),
|
|
1719
|
+
..Default::default()
|
|
1720
|
+
}),
|
|
1721
|
+
scheduler_max_wall_ms: Some(60_000),
|
|
1722
|
+
plan_tool_enabled: Some(true),
|
|
1723
|
+
..RunConfig::default()
|
|
1724
|
+
},
|
|
1725
|
+
};
|
|
1726
|
+
let json = serde_json::to_string(&event).expect("serialize");
|
|
1727
|
+
let parsed: KernelInputEvent = serde_json::from_str(&json).expect("deserialize");
|
|
1728
|
+
assert!(matches!(parsed, KernelInputEvent::ConfigureRun { .. }));
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1545
1731
|
#[test]
|
|
1546
1732
|
fn governance_ask_user_suspends_until_resume() {
|
|
1547
1733
|
let mut runtime = KernelRuntime::new(LoopPolicy::default());
|
|
@@ -1937,6 +2123,60 @@ mod tests {
|
|
|
1937
2123
|
)));
|
|
1938
2124
|
}
|
|
1939
2125
|
|
|
2126
|
+
#[test]
|
|
2127
|
+
fn load_workflow_self_bootstraps_with_no_prior_start_run() {
|
|
2128
|
+
// K1: a stateless `runWorkflow` caller fires `LoadWorkflow` with NO preceding `StartRun`. The
|
|
2129
|
+
// host path now self-bootstraps the run (parity with the agent-reachable `SubmitWorkflow`), so
|
|
2130
|
+
// the DAG installs and drives to completion exactly as the started-path test above.
|
|
2131
|
+
use crate::orchestration::workflow::fanout_synthesize;
|
|
2132
|
+
use crate::types::result::{LoopResult, SubAgentResult, TerminationReason};
|
|
2133
|
+
|
|
2134
|
+
let mut runtime = KernelRuntime::new(LoopPolicy::default());
|
|
2135
|
+
// NOTE: deliberately no StartRun here — that is the whole point of K1.
|
|
2136
|
+
|
|
2137
|
+
let spec =
|
|
2138
|
+
fanout_synthesize(vec![RuntimeTask::new("w0"), RuntimeTask::new("w1")], RuntimeTask::new("synth"));
|
|
2139
|
+
let step = runtime.step(KernelInput::new(KernelInputEvent::LoadWorkflow {
|
|
2140
|
+
spec,
|
|
2141
|
+
parent_session_id: "sess".to_string(),
|
|
2142
|
+
resumed_completed: Vec::new(),
|
|
2143
|
+
resumed_submissions: Vec::new(),
|
|
2144
|
+
}));
|
|
2145
|
+
let batch = step
|
|
2146
|
+
.observations
|
|
2147
|
+
.iter()
|
|
2148
|
+
.find_map(|o| match o {
|
|
2149
|
+
KernelObservation::WorkflowBatchSpawned { nodes, .. } => Some(nodes.clone()),
|
|
2150
|
+
_ => None,
|
|
2151
|
+
})
|
|
2152
|
+
.expect("workflow_batch_spawned even without a prior StartRun");
|
|
2153
|
+
assert_eq!(batch.len(), 2);
|
|
2154
|
+
|
|
2155
|
+
let complete = |runtime: &mut KernelRuntime, id: &str| {
|
|
2156
|
+
runtime.step(KernelInput::new(KernelInputEvent::SubAgentCompleted {
|
|
2157
|
+
result: SubAgentResult {
|
|
2158
|
+
agent_id: compact_str::CompactString::new(id),
|
|
2159
|
+
result: LoopResult {
|
|
2160
|
+
termination: TerminationReason::Completed,
|
|
2161
|
+
final_message: None,
|
|
2162
|
+
turns_used: 1,
|
|
2163
|
+
total_tokens_used: 1,
|
|
2164
|
+
loop_continue: None,
|
|
2165
|
+
classify_branch: None,
|
|
2166
|
+
tournament_winner: None,
|
|
2167
|
+
},
|
|
2168
|
+
},
|
|
2169
|
+
}))
|
|
2170
|
+
};
|
|
2171
|
+
complete(&mut runtime, "wf-node0");
|
|
2172
|
+
complete(&mut runtime, "wf-node1");
|
|
2173
|
+
let step = complete(&mut runtime, "wf-node2");
|
|
2174
|
+
assert!(step.observations.iter().any(|o| matches!(
|
|
2175
|
+
o,
|
|
2176
|
+
KernelObservation::WorkflowCompleted { completed, .. } if completed.len() == 3
|
|
2177
|
+
)));
|
|
2178
|
+
}
|
|
2179
|
+
|
|
1940
2180
|
#[test]
|
|
1941
2181
|
fn submit_workflow_nodes_input_appends_a_node_over_the_abi() {
|
|
1942
2182
|
// R3-1: exercise the full serde round-trip of SubmitWorkflowNodes + WorkflowNode over the
|
|
@@ -7,6 +7,7 @@ use crate::runtime::session::RollbackReason;
|
|
|
7
7
|
use crate::syscall::{Disposition, Syscall};
|
|
8
8
|
use crate::types::message::Message;
|
|
9
9
|
use crate::types::result::SubAgentResult;
|
|
10
|
+
use crate::types::task::RuntimeTask;
|
|
10
11
|
|
|
11
12
|
impl LoopStateMachine {
|
|
12
13
|
/// Whether a workflow DAG is currently in flight.
|
|
@@ -14,6 +15,22 @@ impl LoopStateMachine {
|
|
|
14
15
|
self.workflow.is_some()
|
|
15
16
|
}
|
|
16
17
|
|
|
18
|
+
/// K1: bring the host `LoadWorkflow` path to parity with the agent-reachable `SubmitWorkflow`,
|
|
19
|
+
/// which already bootstraps a run when none is active. If the root task is still `Ready` (the host
|
|
20
|
+
/// never fired `StartRun` — e.g. a stateless `runWorkflow` caller), run the same initialization
|
|
21
|
+
/// `StartRun` performs so the DAG installs onto a live run. No-op once the root has left `Ready`
|
|
22
|
+
/// (host started it, or we already bootstrapped), so it is safe to call unconditionally and carries
|
|
23
|
+
/// no behavior change for runs that were started normally. The `CallLLM` action `start` returns is
|
|
24
|
+
/// discarded — the workflow drives nodes, not a root provider turn, exactly as the SDK's previous
|
|
25
|
+
/// `start_run` + `load_workflow` sequence already did.
|
|
26
|
+
pub fn ensure_started_for_workflow(&mut self, spec: &crate::orchestration::workflow::WorkflowSpec) {
|
|
27
|
+
if !matches!(self.lifecycle(), TaskState::Ready) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
let goal = format!("workflow:{} nodes", spec.nodes.len());
|
|
31
|
+
let _ = self.start(RuntimeTask::new(goal));
|
|
32
|
+
}
|
|
33
|
+
|
|
17
34
|
/// W0: load a workflow DAG and spawn its first gated batch. On an invalid spec (cycle /
|
|
18
35
|
/// out-of-range dependency) the workflow is not installed and the loop continues with a
|
|
19
36
|
/// rollback note, mirroring how a denied effect is surfaced.
|
|
@@ -10,6 +10,8 @@ from deepstrike._kernel import (
|
|
|
10
10
|
SkillMetadata,
|
|
11
11
|
)
|
|
12
12
|
from deepstrike.runtime import (
|
|
13
|
+
run_agent,
|
|
14
|
+
run_fanout,
|
|
13
15
|
RuntimeRunner,
|
|
14
16
|
RuntimeOptions,
|
|
15
17
|
ResourceQuota,
|
|
@@ -106,6 +108,9 @@ from deepstrike.collaboration import (
|
|
|
106
108
|
CreatorVerifierMode, OrchestrationMode, CreatorVerifierMetrics,
|
|
107
109
|
)
|
|
108
110
|
__all__ = [
|
|
111
|
+
# ── Start here: canonical entry points ──
|
|
112
|
+
"run_agent",
|
|
113
|
+
"run_fanout",
|
|
109
114
|
"RuntimeRunner",
|
|
110
115
|
"RuntimeOptions",
|
|
111
116
|
"builtin_reducers",
|
|
@@ -47,13 +47,15 @@ from .ollama import OllamaProvider
|
|
|
47
47
|
from .kimi import KimiProvider, KimiAnthropicProvider
|
|
48
48
|
from .gemini import GeminiProvider
|
|
49
49
|
from .glm import GLMProvider, GLMAnthropicProvider
|
|
50
|
+
# v0.2.3 parity: per-backend factory functions are the public surface; the dual classes above remain
|
|
51
|
+
# importable for advanced subclassing but are no longer advertised in __all__.
|
|
52
|
+
from .factories import deepseek, kimi, qwen, glm, minimax, gemini, ollama
|
|
50
53
|
|
|
51
54
|
__all__ = [
|
|
52
55
|
"LLMProvider", "RenderedContext", "ProviderRunState", "RuntimePolicy", "AnthropicProvider", "OpenAIProvider",
|
|
53
56
|
"OpenAIResponsesProvider", "OpenAIResponsesAdapter",
|
|
54
|
-
|
|
55
|
-
"
|
|
56
|
-
"KimiProvider", "KimiAnthropicProvider", "GeminiProvider", "GLMProvider", "GLMAnthropicProvider",
|
|
57
|
+
# Backend factories (one per backend; `protocol=` selects the wire where a backend speaks both):
|
|
58
|
+
"deepseek", "kimi", "qwen", "glm", "minimax", "gemini", "ollama",
|
|
57
59
|
"RetryConfig", "CircuitBreaker", "normalize_tool_call", "parse_tool_arguments",
|
|
58
60
|
"TokenUsage", "ProviderToolSpec",
|
|
59
61
|
"to_anthropic_content", "to_anthropic_messages",
|