deepstrike 0.2.22__tar.gz → 0.2.24__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.22 → deepstrike-0.2.24}/Cargo.lock +5 -5
- {deepstrike-0.2.22 → deepstrike-0.2.24}/Cargo.toml +2 -2
- {deepstrike-0.2.22 → deepstrike-0.2.24}/PKG-INFO +1 -1
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/__init__.py +10 -1
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/governance.py +32 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/harness/harness.py +45 -22
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/providers/anthropic.py +35 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/providers/stream.py +16 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/execution_plane.py +78 -3
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/mcp_proxy_plane.py +2 -1
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/process_sandbox_plane.py +2 -1
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/remote_vpc_plane.py +2 -1
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/runner.py +75 -5
- deepstrike-0.2.24/deepstrike/tools/__init__.py +9 -0
- deepstrike-0.2.24/deepstrike/tools/errors.py +135 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/tools/execution.py +2 -1
- {deepstrike-0.2.22 → deepstrike-0.2.24}/pyproject.toml +1 -1
- deepstrike-0.2.22/deepstrike/tools/__init__.py +0 -5
- {deepstrike-0.2.22 → deepstrike-0.2.24}/README.md +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/Cargo.toml +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/context/compression.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/context/config.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/context/dashboard.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/context/manager.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/context/mod.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/context/partitions.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/context/pressure.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/context/renderer.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/context/renewal.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/context/sections.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/context/skill_catalog.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/context/snapshot.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/context/summarizer.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/context/task_state.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/context/text.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/context/token_engine.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/governance/audit.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/governance/constraint.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/governance/mod.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/governance/permission.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/governance/pipeline.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/governance/quota.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/governance/rate_limit.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/governance/sandbox.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/governance/tool_decision.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/governance/veto.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/harness/eval.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/harness/mod.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/lib.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/memory/curator.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/memory/durable.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/memory/extractor.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/memory/idle_pipeline.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/memory/mod.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/memory/runtime.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/memory/semantic.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/memory/session.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/memory/synthesis.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/memory/trace_analyzer.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/memory/working.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/mm/handle.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/mm/memory.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/mm/mod.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/orchestration/mod.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/orchestration/task_graph.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/orchestration/tournament.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/orchestration/workflow/mod.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/orchestration/workflow/run.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/proc/mod.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/runtime/event_log.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/runtime/kernel.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/runtime/mod.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/runtime/repair.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/runtime/replay.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/runtime/session.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/runtime/snapshot.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/scheduler/milestone.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/scheduler/mod.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/scheduler/policy.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/scheduler/rollback.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/scheduler/state_machine/capability.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/scheduler/state_machine/eviction.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/scheduler/state_machine/gate.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/scheduler/state_machine/milestone_exec.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/scheduler/state_machine/mod.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/scheduler/state_machine/process.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/scheduler/state_machine/signal.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/scheduler/state_machine/tests.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/scheduler/state_machine/workflow.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/scheduler/tcb.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/signals/attention.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/signals/mod.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/signals/queue.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/signals/router.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/syscall/mod.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/types/agent.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/types/capability.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/types/contract.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/types/error.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/types/message.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/types/milestone.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/types/mod.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/types/model.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/types/policy.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/types/result.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/types/signal.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/types/skill.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-core/src/types/task.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-py/Cargo.toml +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/crates/deepstrike-py/src/lib.rs +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/collaboration/__init__.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/collaboration/contract.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/collaboration/handoff.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/collaboration/harness.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/collaboration/modes.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/collaboration/pool.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/harness/__init__.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/kernel/__init__.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/knowledge/__init__.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/knowledge/source.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/memory/__init__.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/memory/agent.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/memory/in_memory_store.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/memory/protocols.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/memory/working.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/providers/__init__.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/providers/base.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/providers/deepseek.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/providers/gemini.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/providers/glm.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/providers/kimi.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/providers/minimax.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/providers/ollama.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/providers/openai.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/providers/openai_responses.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/providers/qwen.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/providers/replay.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/providers/replay_validator.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/__init__.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/archive.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/credential_vault.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/eval.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/filtered_plane.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/kernel_event_log.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/kernel_step.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/large_result_spool.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/os_profile.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/os_snapshot.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/output_schema.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/provider_replay.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/reducers.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/replay_fixture.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/replay_provider.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/replay_sanitize.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/session_log.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/session_repair.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/sub_agent_orchestrator.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/workflow_control_flow.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/workflow_store.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/runtime/worktree_plane.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/safety/__init__.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/safety/permissions.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/signals/__init__.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/signals/gateway.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/signals/scheduled.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/signals/types.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/skills/__init__.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/skills/registry.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/skills/watcher.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/tools/builtin/__init__.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/tools/builtin/read_file.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/tools/registry.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/deepstrike/types/__init__.py +0 -0
- {deepstrike-0.2.22 → deepstrike-0.2.24}/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.24"
|
|
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.24"
|
|
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.24"
|
|
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.24"
|
|
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.24"
|
|
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.24"
|
|
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.24" }
|
|
13
13
|
notify = "6"
|
|
14
14
|
serde = { version = "1", features = ["derive"] }
|
|
15
15
|
serde_json = "1"
|
|
@@ -64,7 +64,11 @@ from deepstrike.providers import (
|
|
|
64
64
|
PermissionRequestEvent, PermissionResolvedEvent, PermissionResponse, ToolArgumentRepairedEvent,
|
|
65
65
|
RetryConfig, CircuitBreaker, TokenUsage, ProviderToolSpec,
|
|
66
66
|
)
|
|
67
|
-
from deepstrike.tools import
|
|
67
|
+
from deepstrike.tools import (
|
|
68
|
+
RegisteredTool, tool, streaming_tool, validate_tool_arguments, execute_tools, read_file,
|
|
69
|
+
ToolError, safe_tool, ok, fail, format_tool_error,
|
|
70
|
+
)
|
|
71
|
+
from deepstrike.providers.stream import ToolAuditFailedEvent
|
|
68
72
|
from deepstrike.memory import (
|
|
69
73
|
WorkingMemory,
|
|
70
74
|
DreamStore, DreamResult, SessionData, MemoryEntry, CurationResult, CurationStats,
|
|
@@ -75,6 +79,9 @@ from deepstrike.harness import (
|
|
|
75
79
|
QualityGate,
|
|
76
80
|
SinglePassHarness, HarnessLoop, EvalLoopHarness,
|
|
77
81
|
HarnessRequest, HarnessOutcome,
|
|
82
|
+
# I3.1: surface harness types so hosts can construct verdicts and stream-event handlers
|
|
83
|
+
# without importing from deepstrike.harness.harness directly.
|
|
84
|
+
HarnessEvent, CriterionResult,
|
|
78
85
|
)
|
|
79
86
|
from deepstrike.skills import SkillRegistry
|
|
80
87
|
from deepstrike.knowledge import KnowledgeSource
|
|
@@ -136,11 +143,13 @@ __all__ = [
|
|
|
136
143
|
"PermissionRequestEvent", "PermissionResolvedEvent", "PermissionResponse", "ToolArgumentRepairedEvent",
|
|
137
144
|
"RetryConfig", "CircuitBreaker", "TokenUsage", "ProviderToolSpec",
|
|
138
145
|
"RegisteredTool", "tool", "streaming_tool", "validate_tool_arguments", "execute_tools", "read_file",
|
|
146
|
+
"ToolError", "safe_tool", "ok", "fail", "format_tool_error", "ToolAuditFailedEvent",
|
|
139
147
|
"WorkingMemory",
|
|
140
148
|
"DreamStore", "DreamResult", "SessionData", "MemoryEntry", "CurationResult", "CurationStats",
|
|
141
149
|
"PermissionManager", "PermissionMode", "Permission", "PermissionDecision",
|
|
142
150
|
"QualityGate",
|
|
143
151
|
"SinglePassHarness", "HarnessLoop", "EvalLoopHarness", "HarnessRequest", "HarnessOutcome",
|
|
152
|
+
"HarnessEvent", "CriterionResult",
|
|
144
153
|
"SkillRegistry",
|
|
145
154
|
"KnowledgeSource",
|
|
146
155
|
"RuntimeSignal", "SignalSource", "ScheduledPrompt", "SignalGateway",
|
|
@@ -28,6 +28,38 @@ class GovernancePolicy:
|
|
|
28
28
|
vetoes: list[str] = field(default_factory=list)
|
|
29
29
|
rate_limits: list[GovernanceRateLimit] = field(default_factory=list)
|
|
30
30
|
constraints: list[dict[str, Any]] = field(default_factory=list)
|
|
31
|
+
# I5: when True (default), the runner pre-filters denied tools out of the schema. Mirrors Node.
|
|
32
|
+
surface_denied_in_system: bool = True
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def governance_filter_schema(tools: list, policy: "GovernancePolicy | None") -> tuple[list, list[str]]:
|
|
36
|
+
"""I5: bucket tools into (allowed, denied) per the policy. Pure. Mirrors Node ``governanceFilterSchema``."""
|
|
37
|
+
if policy is None:
|
|
38
|
+
return tools, []
|
|
39
|
+
vetoes = set(policy.vetoes or [])
|
|
40
|
+
allowed: list = []
|
|
41
|
+
denied: list[str] = []
|
|
42
|
+
def matches(pat: str, name: str) -> bool:
|
|
43
|
+
return pat == name or (pat.endswith("*") and name.startswith(pat[:-1]))
|
|
44
|
+
for t in tools:
|
|
45
|
+
name = t.name if hasattr(t, "name") else (t.get("name") if isinstance(t, dict) else None)
|
|
46
|
+
if name is None:
|
|
47
|
+
allowed.append(t)
|
|
48
|
+
continue
|
|
49
|
+
if name in vetoes:
|
|
50
|
+
denied.append(name)
|
|
51
|
+
continue
|
|
52
|
+
action = policy.default_action or "allow"
|
|
53
|
+
for r in (policy.rules or []):
|
|
54
|
+
pat = r.pattern if hasattr(r, "pattern") else r.get("pattern")
|
|
55
|
+
act = r.action if hasattr(r, "action") else r.get("action")
|
|
56
|
+
if pat is not None and matches(pat, name):
|
|
57
|
+
action = act
|
|
58
|
+
if action == "deny":
|
|
59
|
+
denied.append(name)
|
|
60
|
+
else:
|
|
61
|
+
allowed.append(t)
|
|
62
|
+
return allowed, denied
|
|
31
63
|
|
|
32
64
|
|
|
33
65
|
def governance_policy_to_kernel_event(policy: GovernancePolicy) -> dict[str, Any]:
|
|
@@ -16,6 +16,10 @@ class Criterion:
|
|
|
16
16
|
text: str
|
|
17
17
|
required: bool = True
|
|
18
18
|
weight: float = 1.0
|
|
19
|
+
# I3.3 (A4): optional stable id from the host's contract layer (threaded to verdict_fn).
|
|
20
|
+
id: "str | None" = None
|
|
21
|
+
# I3.3 (A4): host hint — host has a deterministic check for this criterion.
|
|
22
|
+
machine_checkable: "bool | None" = None
|
|
19
23
|
|
|
20
24
|
|
|
21
25
|
@dataclass
|
|
@@ -160,6 +164,9 @@ class SinglePassHarness:
|
|
|
160
164
|
|
|
161
165
|
|
|
162
166
|
class EvalLoopHarness:
|
|
167
|
+
"""I3.4 (A1): deprecated — prefer ``HarnessLoop`` with ``verdict_fn`` for host-defined
|
|
168
|
+
judgment. ``EvalLoopHarness.stream()`` does NOT honor ``gate`` (only ``.run()`` does);
|
|
169
|
+
``HarnessLoop`` runs the eval loop uniformly across stream and run."""
|
|
163
170
|
def __init__(self, runner: "RuntimeRunner", gate: "QualityGate", max_attempts: int = 3):
|
|
164
171
|
self._runner = runner
|
|
165
172
|
self._gate = gate
|
|
@@ -186,11 +193,16 @@ class HarnessLoop:
|
|
|
186
193
|
*,
|
|
187
194
|
max_attempts: int = 3,
|
|
188
195
|
skill_dir: str | None = None,
|
|
196
|
+
# I3.2 (A2/A3): host-supplied judgment. Receives kwargs (goal, criteria, attempt, result);
|
|
197
|
+
# returns Verdict to short-circuit the LLM eval, or None/Awaitable[None] to defer. Mirrors
|
|
198
|
+
# the Node SDK ``verdictFn``.
|
|
199
|
+
verdict_fn=None,
|
|
189
200
|
):
|
|
190
201
|
self._runner = runner
|
|
191
202
|
self._eval_provider = eval_provider
|
|
192
203
|
self._max_attempts = max_attempts
|
|
193
204
|
self._skill_dir = pathlib.Path(skill_dir) if skill_dir else None
|
|
205
|
+
self._verdict_fn = verdict_fn
|
|
194
206
|
|
|
195
207
|
async def run(self, request: HarnessRequest) -> HarnessOutcome:
|
|
196
208
|
# R3-1: collect nodes the agent submits while running under the harness (dynamic fan-out in
|
|
@@ -251,30 +263,41 @@ class HarnessLoop:
|
|
|
251
263
|
|
|
252
264
|
yield SupervisingEvent()
|
|
253
265
|
|
|
254
|
-
#
|
|
255
|
-
#
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
266
|
+
# I3.2 (A2/A3): host-supplied verdict_fn short-circuits the LLM eval. Returning None
|
|
267
|
+
# (or awaitable None) defers to the built-in eval below — enables hybrid judgment.
|
|
268
|
+
verdict = None
|
|
269
|
+
skill_candidate = None
|
|
270
|
+
if self._verdict_fn is not None:
|
|
271
|
+
result = self._verdict_fn(goal=request.goal, criteria=criteria, attempt=attempt, result=last_result)
|
|
272
|
+
if hasattr(result, "__await__"):
|
|
273
|
+
result = await result
|
|
274
|
+
verdict = result
|
|
275
|
+
if verdict is None:
|
|
276
|
+
# #6 (0.5.0): the eval/verdict compute is the kernel's stateless free functions (was the
|
|
277
|
+
# EvalPipeline state machine). Build the eval prompt, call the eval LLM, parse the verdict.
|
|
278
|
+
eval_msgs = build_eval_messages(request.goal, criteria, last_result, attempt, True)
|
|
279
|
+
eval_text = ""
|
|
280
|
+
eval_system = "\n\n".join(m.content for m in eval_msgs if m.role == "system")
|
|
281
|
+
eval_turns = [m for m in eval_msgs if m.role != "system"]
|
|
282
|
+
eval_context = RenderedContext(system_text=eval_system, turns=eval_turns)
|
|
283
|
+
async for evt in self._eval_provider.stream(eval_context, [], extensions=None):
|
|
284
|
+
if isinstance(evt, TextDelta):
|
|
285
|
+
eval_text += evt.delta
|
|
286
|
+
|
|
287
|
+
parsed = parse_verdict(eval_text)
|
|
288
|
+
verdict = Verdict(
|
|
289
|
+
passed=parsed.passed,
|
|
290
|
+
overall_score=parsed.overall_score,
|
|
291
|
+
feedback=parsed.feedback,
|
|
292
|
+
details=[
|
|
293
|
+
CriterionResult(criterion=d.criterion, passed=d.passed, score=d.score, feedback=d.feedback)
|
|
294
|
+
for d in (parsed.details or [])
|
|
295
|
+
],
|
|
296
|
+
)
|
|
297
|
+
skill_candidate = parsed.skill_candidate
|
|
275
298
|
|
|
276
299
|
if verdict.passed:
|
|
277
|
-
sc =
|
|
300
|
+
sc = skill_candidate
|
|
278
301
|
if sc and self._skill_dir:
|
|
279
302
|
lines = ["---", f"name: {sc.name}", f"description: {sc.description}"]
|
|
280
303
|
if sc.when_to_use:
|
|
@@ -222,6 +222,8 @@ class AnthropicProvider:
|
|
|
222
222
|
system = self._build_system(context, strategy)
|
|
223
223
|
tool_defs = self._build_tools(tools, anchor_cache=not isinstance(system, list), strategy=strategy)
|
|
224
224
|
_assert_cache_budget(system, len(tools))
|
|
225
|
+
# I1: capture which slots will carry cache_control for pro-rata attribution at usage time.
|
|
226
|
+
slot_bp = _count_cache_control_slots(system, tool_defs, msgs)
|
|
225
227
|
|
|
226
228
|
native_blocks: dict[int, dict] = {}
|
|
227
229
|
tool_blocks: dict[int, dict] = {}
|
|
@@ -254,12 +256,14 @@ class AnthropicProvider:
|
|
|
254
256
|
# input_tokens is the FULL prompt size (uncached + cache
|
|
255
257
|
# read + cache write) for accurate context accounting.
|
|
256
258
|
full_input = uncached_input + cache_read + cache_creation
|
|
259
|
+
by_slot = _estimate_cache_read_by_slot(cache_read, slot_bp)
|
|
257
260
|
yield UsageEvent(
|
|
258
261
|
total_tokens=full_input + output_tokens,
|
|
259
262
|
input_tokens=full_input,
|
|
260
263
|
output_tokens=output_tokens,
|
|
261
264
|
cache_read_input_tokens=cache_read,
|
|
262
265
|
cache_creation_input_tokens=cache_creation,
|
|
266
|
+
cache_read_input_tokens_by_slot=by_slot,
|
|
263
267
|
)
|
|
264
268
|
elif event.type == "content_block_start":
|
|
265
269
|
idx = event.index
|
|
@@ -341,6 +345,37 @@ def _resolve_cache_breakpoint_strategy(extensions: "dict | None") -> str:
|
|
|
341
345
|
return "default"
|
|
342
346
|
|
|
343
347
|
|
|
348
|
+
def _count_cache_control_slots(system, tool_defs, msgs) -> dict:
|
|
349
|
+
"""I1: which slots of the outgoing request carry a ``cache_control`` breakpoint. Mirrors Node."""
|
|
350
|
+
sys_bp = isinstance(system, list) and any((isinstance(b, dict) and b.get("cache_control") is not None) for b in system)
|
|
351
|
+
tool_bp = bool(tool_defs) and any((isinstance(t, dict) and t.get("cache_control") is not None) for t in tool_defs)
|
|
352
|
+
msg_bp = False
|
|
353
|
+
for m in msgs or []:
|
|
354
|
+
content = m.get("content") if isinstance(m, dict) else None
|
|
355
|
+
if isinstance(content, list):
|
|
356
|
+
if any((isinstance(b, dict) and b.get("cache_control") is not None) for b in content):
|
|
357
|
+
msg_bp = True
|
|
358
|
+
break
|
|
359
|
+
return {"system": sys_bp, "tools": tool_bp, "messages": msg_bp}
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
def _estimate_cache_read_by_slot(cache_read: int, slot_bp: dict) -> "dict | None":
|
|
363
|
+
"""I1: split ``cache_read_input_tokens`` evenly across contributing slots. Remainder lands on the
|
|
364
|
+
first contributing slot to keep the sum exact. Returns None when no cache read or no slot
|
|
365
|
+
contributed — consumers see the field absent rather than all zeros. Mirrors Node."""
|
|
366
|
+
if cache_read <= 0:
|
|
367
|
+
return None
|
|
368
|
+
contributors = [s for s in ("system", "tools", "messages") if slot_bp.get(s)]
|
|
369
|
+
if not contributors:
|
|
370
|
+
return None
|
|
371
|
+
share = cache_read // len(contributors)
|
|
372
|
+
remainder = cache_read - share * len(contributors)
|
|
373
|
+
out: dict = {}
|
|
374
|
+
for i, slot in enumerate(contributors):
|
|
375
|
+
out[slot] = share + (remainder if i == 0 else 0)
|
|
376
|
+
return out
|
|
377
|
+
|
|
378
|
+
|
|
344
379
|
def _apply_message_cache_control(msgs: list[dict], frozen_prefix_len: "int | None" = None, strategy: str = "default") -> None:
|
|
345
380
|
"""Place the (<=2) message-history cache breakpoints. The final message always
|
|
346
381
|
gets one (writes the current full prefix). The second is placed by one of two
|
|
@@ -63,6 +63,9 @@ class UsageEvent:
|
|
|
63
63
|
# Cost breakdown (subset of input_tokens): reads bill ~0.1x, writes ~1.25x.
|
|
64
64
|
cache_read_input_tokens: int = 0
|
|
65
65
|
cache_creation_input_tokens: int = 0
|
|
66
|
+
# I1: pro-rata per-slot attribution of cache_read_input_tokens (Anthropic only). None when the
|
|
67
|
+
# provider doesn't honor cache_control. Shape: {"system": int?, "tools": int?, "messages": int?}.
|
|
68
|
+
cache_read_input_tokens_by_slot: "dict | None" = None
|
|
66
69
|
|
|
67
70
|
|
|
68
71
|
@dataclass
|
|
@@ -123,6 +126,18 @@ class ToolDeniedEvent:
|
|
|
123
126
|
reason: str = ""
|
|
124
127
|
|
|
125
128
|
|
|
129
|
+
@dataclass
|
|
130
|
+
class ToolAuditFailedEvent:
|
|
131
|
+
"""A tool's ``ctx.audit(label, fn)`` best-effort side-effect threw. The tool itself completed
|
|
132
|
+
successfully (no ``is_error`` flip, no retry); this event lets the host log / monitor that an
|
|
133
|
+
audit-store / metrics-emit / non-essential persistence step failed."""
|
|
134
|
+
type: str = "tool_audit_failed"
|
|
135
|
+
call_id: str = ""
|
|
136
|
+
name: str = ""
|
|
137
|
+
label: str = ""
|
|
138
|
+
error: str = ""
|
|
139
|
+
|
|
140
|
+
|
|
126
141
|
@dataclass
|
|
127
142
|
class WorkflowNodesSubmittedEvent:
|
|
128
143
|
"""R3-1: a workflow node's agent called the ``submit_workflow_nodes`` tool. The runner surfaces
|
|
@@ -146,5 +161,6 @@ StreamEvent = Union[
|
|
|
146
161
|
PermissionResolvedEvent,
|
|
147
162
|
ToolArgumentRepairedEvent,
|
|
148
163
|
ToolDeniedEvent,
|
|
164
|
+
ToolAuditFailedEvent,
|
|
149
165
|
WorkflowNodesSubmittedEvent,
|
|
150
166
|
]
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
|
+
import inspect
|
|
4
5
|
import json
|
|
6
|
+
import warnings
|
|
5
7
|
from collections.abc import AsyncIterable, AsyncIterator
|
|
6
8
|
from dataclasses import dataclass
|
|
7
9
|
from pathlib import Path
|
|
@@ -13,12 +15,14 @@ from deepstrike.providers.stream import (
|
|
|
13
15
|
PermissionResolvedEvent,
|
|
14
16
|
PermissionResponse,
|
|
15
17
|
StreamEvent,
|
|
18
|
+
ToolAuditFailedEvent,
|
|
16
19
|
ToolDeltaEvent,
|
|
17
20
|
ToolDeniedEvent,
|
|
18
21
|
ToolResultEvent,
|
|
19
22
|
ToolSuspendEvent,
|
|
20
23
|
ToolArgumentRepairedEvent,
|
|
21
24
|
)
|
|
25
|
+
from deepstrike.tools.errors import format_tool_error
|
|
22
26
|
from deepstrike.tools.registry import RegisteredTool, normalize_tool_chunk, tool_chunk_text, validate_tool_arguments
|
|
23
27
|
|
|
24
28
|
if TYPE_CHECKING:
|
|
@@ -33,6 +37,39 @@ def _strip_frontmatter(content: str) -> str:
|
|
|
33
37
|
return re.sub(r"^---\n.*?\n---\n?", "", content, count=1, flags=re.DOTALL)
|
|
34
38
|
|
|
35
39
|
|
|
40
|
+
_WARNED_FAILURE_SHAPES: set[str] = set()
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _maybe_warn_failure_shaped_chunk(tool_name: str, delta_text: str) -> None:
|
|
44
|
+
"""One-shot heuristic: detect when a streaming tool yielded text that *looks* like a failure
|
|
45
|
+
envelope. The runtime cannot block the tool from doing it, but we warn (once per tool) so
|
|
46
|
+
the author migrates to raising — the canonical "streaming tool fails" path. Aligns with the
|
|
47
|
+
non-streaming ``tool()`` / ``safe_tool`` contract: failures raise, successes return data."""
|
|
48
|
+
if not delta_text or tool_name in _WARNED_FAILURE_SHAPES:
|
|
49
|
+
return
|
|
50
|
+
trimmed = delta_text.strip()
|
|
51
|
+
if len(trimmed) < 2 or trimmed[0] != "{":
|
|
52
|
+
return
|
|
53
|
+
try:
|
|
54
|
+
parsed = json.loads(trimmed)
|
|
55
|
+
except Exception:
|
|
56
|
+
return
|
|
57
|
+
if not isinstance(parsed, dict):
|
|
58
|
+
return
|
|
59
|
+
looks_like_failure = parsed.get("success") is False or parsed.get("isError") is True or parsed.get("is_error") is True
|
|
60
|
+
if not looks_like_failure:
|
|
61
|
+
return
|
|
62
|
+
_WARNED_FAILURE_SHAPES.add(tool_name)
|
|
63
|
+
warnings.warn(
|
|
64
|
+
f'streaming tool "{tool_name}" yielded a failure-shaped chunk '
|
|
65
|
+
"(success:false / isError:true). Streaming tools should fail by raising; the runtime will "
|
|
66
|
+
"catch and surface the error consistently. Returning a failure-shaped chunk is a foot-gun: "
|
|
67
|
+
"the kernel still sees is_error=False.",
|
|
68
|
+
RuntimeWarning,
|
|
69
|
+
stacklevel=2,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
36
73
|
@dataclass
|
|
37
74
|
class RunContext:
|
|
38
75
|
agent_id: str | None = None
|
|
@@ -45,6 +82,12 @@ class RunContext:
|
|
|
45
82
|
# M3/G4: the working directory a sub-agent's tools should run in (the git worktree created for an
|
|
46
83
|
# ``isolation: "worktree"`` node). Injected by ``WorktreeExecutionPlane``; a cwd-aware tool reads it.
|
|
47
84
|
cwd: str | None = None
|
|
85
|
+
# Per-call best-effort side-effect helper (injected by the execution plane). Wrap audit-log
|
|
86
|
+
# writes, metrics emits, or any non-essential persistence in ``await ctx.audit(label, fn)``;
|
|
87
|
+
# if ``fn`` raises, the failure is surfaced as a ``ToolAuditFailedEvent`` and the tool still
|
|
88
|
+
# completes successfully — avoiding the foot-gun where a transient audit-store outage flips
|
|
89
|
+
# an already-committed write into ``is_error=True`` and triggers a duplicate retry.
|
|
90
|
+
audit: Callable[[str, Callable[[], Awaitable[None] | None]], Awaitable[None]] | None = None
|
|
48
91
|
|
|
49
92
|
|
|
50
93
|
class ExecutionPlane:
|
|
@@ -174,6 +217,29 @@ class LocalExecutionPlane:
|
|
|
174
217
|
error_kind="recoverable",
|
|
175
218
|
)
|
|
176
219
|
return
|
|
220
|
+
# Per-call ``audit`` helper: failures collected here are surfaced as
|
|
221
|
+
# ``ToolAuditFailedEvent`` rather than flipping the main tool result to ``is_error=True``.
|
|
222
|
+
audit_failures: list[tuple[str, str]] = []
|
|
223
|
+
|
|
224
|
+
async def _audit(label: str, fn: Callable[[], Awaitable[None] | None]) -> None:
|
|
225
|
+
try:
|
|
226
|
+
result = fn()
|
|
227
|
+
if inspect.isawaitable(result):
|
|
228
|
+
await result
|
|
229
|
+
except Exception as ae:
|
|
230
|
+
audit_failures.append((label, format_tool_error(ae)))
|
|
231
|
+
|
|
232
|
+
call_ctx = RunContext(
|
|
233
|
+
agent_id=ctx.agent_id,
|
|
234
|
+
skill_dir=ctx.skill_dir,
|
|
235
|
+
dream_store=ctx.dream_store,
|
|
236
|
+
knowledge_source=ctx.knowledge_source,
|
|
237
|
+
on_tool_suspend=ctx.on_tool_suspend,
|
|
238
|
+
on_permission_request=ctx.on_permission_request,
|
|
239
|
+
result_spool=ctx.result_spool,
|
|
240
|
+
cwd=ctx.cwd,
|
|
241
|
+
audit=_audit,
|
|
242
|
+
)
|
|
177
243
|
try:
|
|
178
244
|
kwargs = json.loads(call.arguments or "{}")
|
|
179
245
|
original_args_str = json.dumps(kwargs)
|
|
@@ -195,8 +261,9 @@ class LocalExecutionPlane:
|
|
|
195
261
|
original_arguments=original_args_str,
|
|
196
262
|
repaired_arguments=json.dumps(kwargs),
|
|
197
263
|
)
|
|
198
|
-
# M3/G4: pass the run context (incl. ``cwd``) so cwd-aware
|
|
199
|
-
|
|
264
|
+
# M3/G4: pass the run context (incl. ``cwd``, ``audit``) so cwd-aware / audit-aware tools
|
|
265
|
+
# scope work to the worktree and route best-effort side-effects through the plane.
|
|
266
|
+
output = await registered(_ctx=call_ctx, **kwargs)
|
|
200
267
|
if isinstance(output, AsyncIterable):
|
|
201
268
|
combined = ""
|
|
202
269
|
iterator = output.__aiter__()
|
|
@@ -234,22 +301,30 @@ class LocalExecutionPlane:
|
|
|
234
301
|
continue
|
|
235
302
|
delta = tool_chunk_text(raw)
|
|
236
303
|
combined += delta
|
|
304
|
+
if delta:
|
|
305
|
+
_maybe_warn_failure_shaped_chunk(call.name, delta)
|
|
237
306
|
yield ToolDeltaEvent(
|
|
238
307
|
call_id=call.id, name=call.name, delta=delta,
|
|
239
308
|
chunk=None if isinstance(raw, str) else chunk,
|
|
240
309
|
)
|
|
310
|
+
for label, error in audit_failures:
|
|
311
|
+
yield ToolAuditFailedEvent(call_id=call.id, name=call.name, label=label, error=error)
|
|
241
312
|
yield ToolResultEvent(call_id=call.id, name=call.name, content=combined, is_error=False)
|
|
242
313
|
return
|
|
314
|
+
for label, error in audit_failures:
|
|
315
|
+
yield ToolAuditFailedEvent(call_id=call.id, name=call.name, label=label, error=error)
|
|
243
316
|
yield ToolResultEvent(call_id=call.id, name=call.name, content=str(output), is_error=False)
|
|
244
317
|
except Exception as exc:
|
|
245
318
|
is_fatal = getattr(exc, "is_fatal", False)
|
|
246
319
|
error_kind = getattr(exc, "error_kind", None)
|
|
247
320
|
if error_kind is None:
|
|
248
321
|
error_kind = "fatal" if is_fatal else "recoverable"
|
|
322
|
+
for label, error in audit_failures:
|
|
323
|
+
yield ToolAuditFailedEvent(call_id=call.id, name=call.name, label=label, error=error)
|
|
249
324
|
yield ToolResultEvent(
|
|
250
325
|
call_id=call.id,
|
|
251
326
|
name=call.name,
|
|
252
|
-
content=
|
|
327
|
+
content=format_tool_error(exc),
|
|
253
328
|
is_error=True,
|
|
254
329
|
is_fatal=is_fatal,
|
|
255
330
|
error_kind=error_kind,
|
|
@@ -10,6 +10,7 @@ from typing import TYPE_CHECKING, Any
|
|
|
10
10
|
|
|
11
11
|
from deepstrike._kernel import ToolCall, ToolSchema
|
|
12
12
|
from deepstrike.providers.stream import StreamEvent, ToolResultEvent
|
|
13
|
+
from deepstrike.tools.errors import format_tool_error
|
|
13
14
|
from deepstrike.tools.registry import RegisteredTool
|
|
14
15
|
from deepstrike.runtime.execution_plane import ExecutionPlane, LocalExecutionPlane, RunContext
|
|
15
16
|
from deepstrike.runtime.credential_vault import CredentialVault
|
|
@@ -126,7 +127,7 @@ class _McpConnection:
|
|
|
126
127
|
)
|
|
127
128
|
return (text or json.dumps(result)), result.get("isError", False)
|
|
128
129
|
except Exception as exc:
|
|
129
|
-
return
|
|
130
|
+
return format_tool_error(exc), True
|
|
130
131
|
|
|
131
132
|
async def stop(self) -> None:
|
|
132
133
|
if self._reader_task:
|
|
@@ -6,6 +6,7 @@ import os
|
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
|
|
8
8
|
from deepstrike._kernel import ToolSchema
|
|
9
|
+
from deepstrike.tools.errors import format_tool_error
|
|
9
10
|
from deepstrike.tools.registry import RegisteredTool
|
|
10
11
|
from deepstrike.runtime.execution_plane import LocalExecutionPlane
|
|
11
12
|
|
|
@@ -72,7 +73,7 @@ class ProcessSandboxPlane(LocalExecutionPlane):
|
|
|
72
73
|
combined = combined[: self._max_output_bytes] + b"\n[output truncated]"
|
|
73
74
|
return combined.decode("utf-8", errors="replace"), proc.returncode != 0
|
|
74
75
|
except Exception as exc:
|
|
75
|
-
return
|
|
76
|
+
return format_tool_error(exc), True
|
|
76
77
|
|
|
77
78
|
def _make_bash_tool(self) -> RegisteredTool:
|
|
78
79
|
sandbox = self
|
|
@@ -9,6 +9,7 @@ import aiohttp
|
|
|
9
9
|
|
|
10
10
|
from deepstrike._kernel import ToolCall, ToolSchema
|
|
11
11
|
from deepstrike.providers.stream import StreamEvent, ToolResultEvent
|
|
12
|
+
from deepstrike.tools.errors import format_tool_error
|
|
12
13
|
from deepstrike.tools.registry import RegisteredTool
|
|
13
14
|
from deepstrike.runtime.execution_plane import LocalExecutionPlane, RunContext
|
|
14
15
|
from deepstrike.runtime.credential_vault import CredentialVault
|
|
@@ -97,4 +98,4 @@ class RemoteVpcPlane:
|
|
|
97
98
|
result: dict = await resp.json()
|
|
98
99
|
return result.get("output", ""), bool(result.get("isError", False))
|
|
99
100
|
except Exception as exc:
|
|
100
|
-
return
|
|
101
|
+
return format_tool_error(exc), True
|