deepstrike 0.2.79__tar.gz → 0.2.80__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.79 → deepstrike-0.2.80}/Cargo.lock +14 -6
- {deepstrike-0.2.79 → deepstrike-0.2.80}/Cargo.toml +3 -3
- {deepstrike-0.2.79 → deepstrike-0.2.80}/PKG-INFO +1 -1
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/context/item.rs +21 -1
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/context/manager.rs +351 -3
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/context/partitions.rs +116 -16
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/context/renderer.rs +18 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/checkpoint.rs +24 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/crash_point.rs +8 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/driver/effects.rs +6 -2
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/driver/projection.rs +23 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/driver/provider.rs +21 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/driver/tests.rs +105 -7
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/driver.rs +37 -1
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/effect.rs +42 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/state_machine/mod.rs +19 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-py/src/lib.rs +8 -1
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/__init__.py +16 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/base.py +6 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/canonical_kernel_step.py +33 -0
- deepstrike-0.2.80/deepstrike/runtime/dynamic_workflow.py +279 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/kernel_step.py +6 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/runner.py +152 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/types/content.py +1 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/pyproject.toml +1 -1
- {deepstrike-0.2.79 → deepstrike-0.2.80}/LICENSE +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/README.md +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/Cargo.toml +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/LICENSE +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/benches/kernel_baseline.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/benches/wait_index_baseline.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/benchmark/mod.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/context/compression.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/context/config.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/context/fault.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/context/measurement.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/context/mod.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/context/policy.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/context/pressure.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/context/renewal.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/context/skill_catalog.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/context/summarizer.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/context/task_state.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/context/text.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/context/token_engine.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/context/units.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/context/utility.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/governance/constraint.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/governance/mod.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/governance/permission.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/governance/pipeline.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/governance/quota.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/governance/rate_limit.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/governance/repeat_fuse.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/governance/veto.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/harness/eval.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/harness/mod.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/lexical.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/lib.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/memory/curator.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/memory/durable.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/memory/mod.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/mm/handle.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/mm/memory.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/mm/memory_candidate.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/mm/mod.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/mm/value.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/orchestration/mod.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/orchestration/task_graph.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/orchestration/workflow/mod.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/orchestration/workflow/run.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/proc/mod.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/projection_pairs.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/event_log.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/observation.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/binding.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/command.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/config.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/driver/continuation.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/driver/events.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/driver/planning.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/driver/syscall.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/envelope.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/event.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/fault.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/memory_authority.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/projection.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/record.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/restore.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/root.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/scalar.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/syscall.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/terminal.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/tests.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire/transaction.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel/wire.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/kernel.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/mod.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/repair.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/replay.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/session.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/session_registry_tests.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/runtime/session_wire.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/budget_grant.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/cross_operation.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/entropy.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/mailbox.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/milestone.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/mod.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/policy.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/rollback.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/runnable.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/state_machine/cancellation.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/state_machine/capability.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/state_machine/eviction.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/state_machine/gate.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/state_machine/milestone_exec.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/state_machine/process.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/state_machine/signal.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/state_machine/tests.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/state_machine/workflow.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/tcb.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/scheduler/wait_index.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/signals/attention.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/signals/mod.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/signals/queue.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/signals/router.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/syscall/mod.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/types/agent.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/types/capability.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/types/contract.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/types/durable_content.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/types/error.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/types/message.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/types/milestone.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/types/mod.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/types/policy.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/types/result.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/types/signal.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/types/skill.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-core/src/types/task.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-py/Cargo.toml +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-py/LICENSE +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-tokenizer/Cargo.toml +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-tokenizer/LICENSE +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/crates/deepstrike-tokenizer/src/lib.rs +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/agent.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/collaboration/__init__.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/collaboration/contract.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/collaboration/handoff.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/collaboration/harness.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/collaboration/modes.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/collaboration/pool.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/governance.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/harness/__init__.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/harness/harness.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/harness/judge.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/kernel/__init__.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/kernel/canonical.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/knowledge/__init__.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/knowledge/source.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/memory/__init__.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/memory/agent.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/memory/attestation.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/memory/authority.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/memory/candidate_sink.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/memory/durable.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/memory/durable_candidate_sink.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/memory/durable_lifecycle_store.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/memory/in_memory_store.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/memory/lifecycle.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/memory/protocols.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/memory/ranking.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/memory/recall_projection.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/memory/retention.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/memory/runtime_policy.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/memory/working.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/memory/writer.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/__init__.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/anthropic.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/anthropic_adapter.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/anthropic_compaction.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/anthropic_compatible.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/capability_router.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/credentials.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/embedding.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/factories.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/fallback.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/gemini.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/gemini_adapter.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/model_catalog.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/model_registry.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/ollama.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/ollama_adapter.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/openai.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/openai_chat_adapter.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/openai_responses.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/prepared_request.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/protocol_adapter.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/protocols.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/provider_error.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/qwen.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/replay.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/replay_validator.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/request_plan.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/runtime_registry.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/stop_reason.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/stream.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/usage.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/providers/vendor_profiles.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/__init__.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/_session_event_registry.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/agent_declaration.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/archive.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/context_policy.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/credential_vault.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/durable_content.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/eval.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/eval_dataset.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/event_stream.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/execution_evidence.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/execution_plane.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/facade.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/filtered_plane.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/kernel_event_log.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/kernel_journal.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/loop_driver.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/mcp_proxy_plane.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/os_profile.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/os_snapshot.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/output_schema.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/payload_store.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/process_sandbox_plane.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/provider_replay.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/reaction_checkpoint.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/reactive_session.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/reliability.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/remote_vpc_plane.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/replay_fixture.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/replay_provider.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/replay_sanitize.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/run_group.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/session_log.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/session_repair.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/sub_agent_orchestrator.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/tool_arguments.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/turn_policy.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/workflow_replay.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/workflow_store.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/runtime/worktree_plane.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/safety/__init__.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/safety/permissions.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/signals/__init__.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/signals/gateway.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/signals/scheduled.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/signals/types.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/skills/__init__.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/skills/loader.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/skills/registry.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/skills/watcher.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/tools/__init__.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/tools/builtin/__init__.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/tools/builtin/read_file.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/tools/errors.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/tools/execution.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/tools/registry.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/types/__init__.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/types/agent.py +0 -0
- {deepstrike-0.2.79 → deepstrike-0.2.80}/deepstrike/types/content_policy.py +0 -0
|
@@ -293,7 +293,7 @@ dependencies = [
|
|
|
293
293
|
|
|
294
294
|
[[package]]
|
|
295
295
|
name = "deepstrike-core"
|
|
296
|
-
version = "0.2.
|
|
296
|
+
version = "0.2.80"
|
|
297
297
|
dependencies = [
|
|
298
298
|
"compact_str",
|
|
299
299
|
"deepstrike-tokenizer",
|
|
@@ -305,9 +305,17 @@ dependencies = [
|
|
|
305
305
|
"uuid",
|
|
306
306
|
]
|
|
307
307
|
|
|
308
|
+
[[package]]
|
|
309
|
+
name = "deepstrike-lab"
|
|
310
|
+
version = "0.2.80"
|
|
311
|
+
dependencies = [
|
|
312
|
+
"serde",
|
|
313
|
+
"serde_json",
|
|
314
|
+
]
|
|
315
|
+
|
|
308
316
|
[[package]]
|
|
309
317
|
name = "deepstrike-node"
|
|
310
|
-
version = "0.2.
|
|
318
|
+
version = "0.2.80"
|
|
311
319
|
dependencies = [
|
|
312
320
|
"compact_str",
|
|
313
321
|
"deepstrike-core",
|
|
@@ -319,7 +327,7 @@ dependencies = [
|
|
|
319
327
|
|
|
320
328
|
[[package]]
|
|
321
329
|
name = "deepstrike-py"
|
|
322
|
-
version = "0.2.
|
|
330
|
+
version = "0.2.80"
|
|
323
331
|
dependencies = [
|
|
324
332
|
"compact_str",
|
|
325
333
|
"deepstrike-core",
|
|
@@ -330,7 +338,7 @@ dependencies = [
|
|
|
330
338
|
|
|
331
339
|
[[package]]
|
|
332
340
|
name = "deepstrike-sdk"
|
|
333
|
-
version = "0.2.
|
|
341
|
+
version = "0.2.80"
|
|
334
342
|
dependencies = [
|
|
335
343
|
"async-stream",
|
|
336
344
|
"async-trait",
|
|
@@ -368,7 +376,7 @@ dependencies = [
|
|
|
368
376
|
|
|
369
377
|
[[package]]
|
|
370
378
|
name = "deepstrike-tokenizer"
|
|
371
|
-
version = "0.2.
|
|
379
|
+
version = "0.2.80"
|
|
372
380
|
dependencies = [
|
|
373
381
|
"pretty_assertions",
|
|
374
382
|
"tiktoken-rs",
|
|
@@ -376,7 +384,7 @@ dependencies = [
|
|
|
376
384
|
|
|
377
385
|
[[package]]
|
|
378
386
|
name = "deepstrike-wasm"
|
|
379
|
-
version = "0.2.
|
|
387
|
+
version = "0.2.80"
|
|
380
388
|
dependencies = [
|
|
381
389
|
"compact_str",
|
|
382
390
|
"deepstrike-core",
|
|
@@ -3,13 +3,13 @@ resolver = "2"
|
|
|
3
3
|
members = ["crates/deepstrike-core", "crates/deepstrike-tokenizer", "crates/deepstrike-py"]
|
|
4
4
|
|
|
5
5
|
[workspace.package]
|
|
6
|
-
version = "0.2.
|
|
6
|
+
version = "0.2.80"
|
|
7
7
|
edition = "2024"
|
|
8
8
|
repository = "https://github.com/kongusen/deepstrike"
|
|
9
9
|
|
|
10
10
|
[workspace.dependencies]
|
|
11
|
-
deepstrike-core = { path = "crates/deepstrike-core", version = "0.2.
|
|
12
|
-
deepstrike-tokenizer = { path = "crates/deepstrike-tokenizer", version = "0.2.
|
|
11
|
+
deepstrike-core = { path = "crates/deepstrike-core", version = "0.2.80" }
|
|
12
|
+
deepstrike-tokenizer = { path = "crates/deepstrike-tokenizer", version = "0.2.80" }
|
|
13
13
|
notify = "6"
|
|
14
14
|
serde = { version = "1", features = ["derive"] }
|
|
15
15
|
serde_json = "1"
|
|
@@ -80,6 +80,8 @@ pub enum ItemOrigin {
|
|
|
80
80
|
MemoryRecall,
|
|
81
81
|
/// Reference material the host seeded or pinned.
|
|
82
82
|
Reference,
|
|
83
|
+
/// Shared state a workflow program wrote for the agents it runs (`blackboard:<key>`).
|
|
84
|
+
Blackboard,
|
|
83
85
|
ToolResult,
|
|
84
86
|
DependencyOutput,
|
|
85
87
|
User,
|
|
@@ -105,6 +107,7 @@ impl ItemOrigin {
|
|
|
105
107
|
pub fn for_host_key(key: Option<&str>) -> Self {
|
|
106
108
|
match key {
|
|
107
109
|
Some(key) if key.starts_with("skill:") => Self::Skill,
|
|
110
|
+
Some(key) if key.starts_with("blackboard:") => Self::Blackboard,
|
|
108
111
|
_ => Self::Reference,
|
|
109
112
|
}
|
|
110
113
|
}
|
|
@@ -115,6 +118,7 @@ impl ItemOrigin {
|
|
|
115
118
|
Self::Skill => "skill",
|
|
116
119
|
Self::MemoryRecall => "memory_recall",
|
|
117
120
|
Self::Reference => "reference",
|
|
121
|
+
Self::Blackboard => "blackboard",
|
|
118
122
|
Self::ToolResult => "tool_result",
|
|
119
123
|
Self::DependencyOutput => "dependency_output",
|
|
120
124
|
Self::User => "user",
|
|
@@ -138,6 +142,7 @@ impl ItemOrigin {
|
|
|
138
142
|
Self::Skill => (S::Task, F::Full, L::Until(LeaseEvent::SkillDeactivated), A::Model),
|
|
139
143
|
Self::MemoryRecall => (S::Session, F::Handle, L::Turns(RECALL_LEASE_TURNS), A::Host),
|
|
140
144
|
Self::Reference => (S::Operation, F::Full, L::Permanent, A::Host),
|
|
145
|
+
Self::Blackboard => (S::Workflow, F::Full, L::Permanent, A::Host),
|
|
141
146
|
Self::ToolResult => (S::Task, F::Full, L::Permanent, A::Host),
|
|
142
147
|
Self::DependencyOutput => (S::Edge, F::Handle, L::Permanent, A::Kernel),
|
|
143
148
|
Self::User => (S::Operation, F::Full, L::Permanent, A::Host),
|
|
@@ -164,6 +169,9 @@ pub enum ItemScope {
|
|
|
164
169
|
Session,
|
|
165
170
|
/// The agent's identity, whatever it works on.
|
|
166
171
|
Agent,
|
|
172
|
+
/// A workflow run: every agent it spawns reads it, whatever its context inheritance —
|
|
173
|
+
/// shared state the program hands its agents on purpose, not the parent's transcript.
|
|
174
|
+
Workflow,
|
|
167
175
|
}
|
|
168
176
|
|
|
169
177
|
impl ItemScope {
|
|
@@ -180,6 +188,7 @@ impl ItemScope {
|
|
|
180
188
|
pub fn inherited_by(self, inheritance: crate::types::agent::ContextInheritance) -> bool {
|
|
181
189
|
use crate::types::agent::ContextInheritance as I;
|
|
182
190
|
match (self, inheritance) {
|
|
191
|
+
(Self::Workflow, _) => true,
|
|
183
192
|
(Self::Edge, _) | (_, I::None) => false,
|
|
184
193
|
(Self::Agent, I::SystemOnly) => true,
|
|
185
194
|
(_, I::SystemOnly) => false,
|
|
@@ -350,9 +359,16 @@ pub struct ItemValue {
|
|
|
350
359
|
/// Turn the item arrived (or was last renewed by a fresh recall or upsert).
|
|
351
360
|
#[serde(default)]
|
|
352
361
|
pub injected_turn: u32,
|
|
353
|
-
/// Committed history messages that referenced it.
|
|
362
|
+
/// Committed history messages that referenced it, by any evidence.
|
|
354
363
|
#[serde(default)]
|
|
355
364
|
pub ref_count: u64,
|
|
365
|
+
/// Plan task 4.2 · references by strong evidence: the model asked for the item
|
|
366
|
+
/// (`memory(record_id)`), passed its key or record id in a tool call, or named its key.
|
|
367
|
+
#[serde(default, skip_serializing_if = "is_zero_u64")]
|
|
368
|
+
pub strong_refs: u64,
|
|
369
|
+
/// References by lexical overlap only: the conversation shares the item's distinctive terms.
|
|
370
|
+
#[serde(default, skip_serializing_if = "is_zero_u64")]
|
|
371
|
+
pub lexical_refs: u64,
|
|
356
372
|
/// Reference step (history position) of the last reference; the retention score's recency.
|
|
357
373
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
358
374
|
pub last_referenced_step: Option<u64>,
|
|
@@ -501,6 +517,10 @@ mod tests {
|
|
|
501
517
|
assert!(scope.survives_renewal(), "{scope:?}");
|
|
502
518
|
}
|
|
503
519
|
assert!(!ItemScope::Edge.inherited_by(I::Full));
|
|
520
|
+
for inheritance in [I::None, I::SystemOnly, I::Full] {
|
|
521
|
+
assert!(ItemScope::Workflow.inherited_by(inheritance));
|
|
522
|
+
}
|
|
523
|
+
assert_eq!(ItemOrigin::for_host_key(Some("blackboard:plan")), ItemOrigin::Blackboard);
|
|
504
524
|
assert!(!ItemScope::Edge.survives_renewal());
|
|
505
525
|
}
|
|
506
526
|
|
|
@@ -76,6 +76,9 @@ pub(crate) fn is_exposure_exempt_meta_tool(name: &str) -> bool {
|
|
|
76
76
|
EXPOSURE_EXEMPT_META_TOOLS.contains(&name)
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
/// How many recent (estimate, provider count) pairs the calibration is fitted on.
|
|
80
|
+
pub const ESTIMATE_CALIBRATION_SAMPLES: usize = 8;
|
|
81
|
+
|
|
79
82
|
/// End-of-run context lifecycle metrics (plan task 4.1).
|
|
80
83
|
#[derive(Debug, Clone, Default, PartialEq, Eq)]
|
|
81
84
|
pub struct LifecycleMetrics {
|
|
@@ -132,6 +135,14 @@ pub struct ContextManager {
|
|
|
132
135
|
pub knowledge_enabled: bool,
|
|
133
136
|
pub plan_tool_enabled: bool,
|
|
134
137
|
last_observed_prompt_tokens: Option<u32>,
|
|
138
|
+
/// Plan task 5.1 · the uncalibrated estimate of the last provider request, and the factor (in
|
|
139
|
+
/// parts per million) that brings an estimate to what the provider counted. Both move only on
|
|
140
|
+
/// recorded inputs (the provider's observed count), so replay reproduces them.
|
|
141
|
+
pub(crate) last_request_estimate: u32,
|
|
142
|
+
/// The last few (uncalibrated estimate, provider count) pairs. A provider's count differs
|
|
143
|
+
/// from the kernel's by a roughly fixed overhead (message framing, tool templates) plus a
|
|
144
|
+
/// proportional tokenizer gap, so the calibration is the least-squares line through them.
|
|
145
|
+
pub(crate) estimate_samples: std::collections::VecDeque<(u32, u32)>,
|
|
135
146
|
compression: CompressionPipeline,
|
|
136
147
|
pressure: PressureMonitor,
|
|
137
148
|
renewal: RenewalPolicy,
|
|
@@ -191,6 +202,16 @@ pub struct ContextManager {
|
|
|
191
202
|
pub(crate) retired_history: std::collections::VecDeque<HistoryItemRecord>,
|
|
192
203
|
/// Retired history items dropped from `retired_history` by the cap.
|
|
193
204
|
pub(crate) retired_history_omitted: u32,
|
|
205
|
+
/// Messages that arrived while the history tail still waited for tool results (a memory hit
|
|
206
|
+
/// resolving before a sibling tool in the same batch). A provider requires a call's results to
|
|
207
|
+
/// follow it directly, so these wait until the last result lands.
|
|
208
|
+
pub(crate) held_history: Vec<(CoreMessage, u32)>,
|
|
209
|
+
/// Plan task 1.1c · provider replay state kept with assistant history items, by item id.
|
|
210
|
+
/// Each with the tokens it adds to a request: replay is sent back with its turn, so it
|
|
211
|
+
/// occupies the model's context like the turn's own text.
|
|
212
|
+
pub(crate) item_replays: std::collections::BTreeMap<ItemId, (serde_json::Value, u32)>,
|
|
213
|
+
/// Replay for the assistant message being admitted now (set around one provider completion).
|
|
214
|
+
pub(crate) pending_assistant_replay: Option<serde_json::Value>,
|
|
194
215
|
}
|
|
195
216
|
|
|
196
217
|
impl ContextManager {
|
|
@@ -225,6 +246,8 @@ impl ContextManager {
|
|
|
225
246
|
knowledge_enabled: false,
|
|
226
247
|
plan_tool_enabled: false,
|
|
227
248
|
last_observed_prompt_tokens: None,
|
|
249
|
+
last_request_estimate: 0,
|
|
250
|
+
estimate_samples: std::collections::VecDeque::new(),
|
|
228
251
|
compression,
|
|
229
252
|
pressure,
|
|
230
253
|
renewal,
|
|
@@ -245,6 +268,9 @@ impl ContextManager {
|
|
|
245
268
|
history_tally: std::collections::BTreeMap::new(),
|
|
246
269
|
retired_history: std::collections::VecDeque::new(),
|
|
247
270
|
retired_history_omitted: 0,
|
|
271
|
+
held_history: Vec::new(),
|
|
272
|
+
item_replays: std::collections::BTreeMap::new(),
|
|
273
|
+
pending_assistant_replay: None,
|
|
248
274
|
}
|
|
249
275
|
}
|
|
250
276
|
|
|
@@ -488,11 +514,65 @@ impl ContextManager {
|
|
|
488
514
|
);
|
|
489
515
|
// A provider sees a selected projection, not the entire resident history. Its smaller
|
|
490
516
|
// count must not suppress compaction while the unselected history still triggers renewal.
|
|
491
|
-
|
|
517
|
+
// Calibration may raise the estimate (the provider counts more than the kernel does, as
|
|
518
|
+
// for CJK text or tool templates) but never lowers it: a provider or proxy reporting too
|
|
519
|
+
// little must not delay compaction past the point the kernel's own count calls for.
|
|
520
|
+
let max_tokens = f64::from(self.max_tokens.max(1));
|
|
521
|
+
let raw = self
|
|
522
|
+
.partitions
|
|
523
|
+
.total_tokens(&self.engine)
|
|
524
|
+
.saturating_add(self.replay_tokens());
|
|
525
|
+
let estimated = if self.max_tokens == 0 {
|
|
526
|
+
0.0
|
|
527
|
+
} else {
|
|
528
|
+
f64::from(self.calibrated(raw).max(raw)) / max_tokens
|
|
529
|
+
};
|
|
530
|
+
observed.max(estimated)
|
|
492
531
|
}
|
|
493
532
|
|
|
494
533
|
pub fn set_observed_prompt_tokens(&mut self, tokens: u32) {
|
|
495
534
|
self.last_observed_prompt_tokens = Some(tokens);
|
|
535
|
+
if self.last_request_estimate > 0 {
|
|
536
|
+
if self.estimate_samples.len() == ESTIMATE_CALIBRATION_SAMPLES {
|
|
537
|
+
self.estimate_samples.pop_front();
|
|
538
|
+
}
|
|
539
|
+
self.estimate_samples.push_back((self.last_request_estimate, tokens));
|
|
540
|
+
self.last_request_estimate = 0;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/// Remember `raw`, the uncalibrated estimate of the request about to be sent, and return it
|
|
545
|
+
/// calibrated.
|
|
546
|
+
pub fn note_request_estimate(&mut self, raw: u32) -> u32 {
|
|
547
|
+
self.last_request_estimate = raw;
|
|
548
|
+
self.calibrated(raw)
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/// `tokens` (an uncalibrated estimate) as the provider would count it: through the
|
|
552
|
+
/// least-squares line of the recent samples; with one sample (or samples of one size) by
|
|
553
|
+
/// their mean offset, the gap being mostly fixed overhead; unchanged with none. Integer arithmetic, so replay reproduces
|
|
554
|
+
/// it; bounded to 1/2..4x of the estimate.
|
|
555
|
+
fn calibrated(&self, tokens: u32) -> u32 {
|
|
556
|
+
let n = self.estimate_samples.len() as i128;
|
|
557
|
+
if n == 0 || tokens == 0 {
|
|
558
|
+
return tokens;
|
|
559
|
+
}
|
|
560
|
+
let (mut sx, mut sy, mut sxx, mut sxy) = (0i128, 0i128, 0i128, 0i128);
|
|
561
|
+
for &(x, y) in &self.estimate_samples {
|
|
562
|
+
let (x, y) = (i128::from(x), i128::from(y));
|
|
563
|
+
sx += x;
|
|
564
|
+
sy += y;
|
|
565
|
+
sxx += x * x;
|
|
566
|
+
sxy += x * y;
|
|
567
|
+
}
|
|
568
|
+
let x = i128::from(tokens);
|
|
569
|
+
let denominator = n * sxx - sx * sx;
|
|
570
|
+
let fitted = if n >= 2 && denominator > 0 {
|
|
571
|
+
(sy * sxx - sx * sxy + x * (n * sxy - sx * sy)) / denominator
|
|
572
|
+
} else {
|
|
573
|
+
x + (sy - sx) / n
|
|
574
|
+
};
|
|
575
|
+
fitted.clamp(x / 2, x * 4).clamp(0, i128::from(u32::MAX)) as u32
|
|
496
576
|
}
|
|
497
577
|
|
|
498
578
|
pub fn should_compress(&self) -> PressureAction {
|
|
@@ -587,6 +667,7 @@ impl ContextManager {
|
|
|
587
667
|
// Archived messages have left history — drop their now-orphaned handles (bounds the table).
|
|
588
668
|
if !archived.is_empty() {
|
|
589
669
|
self.prune_orphaned_handles();
|
|
670
|
+
self.prune_item_replays();
|
|
590
671
|
// Compaction rewrote the history prefix — start a fresh collapse generation so
|
|
591
672
|
// surviving handles re-evaluate from Resident (P0-C: the one cache-free un-collapse point).
|
|
592
673
|
self.reset_collapse_generation();
|
|
@@ -650,6 +731,7 @@ impl ContextManager {
|
|
|
650
731
|
// History was rebuilt wholesale — drop handles anchored to messages it no longer carries,
|
|
651
732
|
// and start a fresh collapse generation (P0-C) since the whole prefix changed.
|
|
652
733
|
self.prune_orphaned_handles();
|
|
734
|
+
self.prune_item_replays();
|
|
653
735
|
self.reset_collapse_generation();
|
|
654
736
|
// K1: renewal is a boundary — apply deferred knowledge upserts/removals now.
|
|
655
737
|
self.sweep_knowledge_at_boundary();
|
|
@@ -669,7 +751,7 @@ impl ContextManager {
|
|
|
669
751
|
}
|
|
670
752
|
|
|
671
753
|
pub fn render(&self) -> InternalRenderedContext {
|
|
672
|
-
super::renderer::render_projected(
|
|
754
|
+
let mut rendered = super::renderer::render_projected(
|
|
673
755
|
&self.partitions,
|
|
674
756
|
self.available_input_tokens(),
|
|
675
757
|
&self.engine,
|
|
@@ -677,12 +759,174 @@ impl ContextManager {
|
|
|
677
759
|
&self.handles,
|
|
678
760
|
self.frozen_history_len,
|
|
679
761
|
self.config.collapse_assistant_narration,
|
|
680
|
-
)
|
|
762
|
+
);
|
|
763
|
+
if !self.item_replays.is_empty() {
|
|
764
|
+
let replay_tokens: u32 = rendered
|
|
765
|
+
.turn_items
|
|
766
|
+
.iter()
|
|
767
|
+
.filter_map(|id| self.item_replays.get(id).map(|(_, tokens)| *tokens))
|
|
768
|
+
.sum();
|
|
769
|
+
rendered.estimated_tokens = rendered.estimated_tokens.saturating_add(replay_tokens);
|
|
770
|
+
rendered.turn_replays = rendered
|
|
771
|
+
.turn_items
|
|
772
|
+
.iter()
|
|
773
|
+
.map(|id| self.item_replays.get(id).map(|(replay, _)| replay.clone()))
|
|
774
|
+
.collect();
|
|
775
|
+
}
|
|
776
|
+
rendered
|
|
681
777
|
}
|
|
682
778
|
|
|
683
779
|
// ── History / Knowledge ───────────────────────────────────────────────────
|
|
684
780
|
|
|
781
|
+
/// Plan task 5.1 · the provider summarized history through item `through` server-side. The
|
|
782
|
+
/// covered items leave as compacted (extended to the end of a tool transaction, never split),
|
|
783
|
+
/// and one `provider_summary` item heads history in their place, rendering `replay` (the
|
|
784
|
+
/// provider's block) — so pressure, renewal and the next render see what the model sees.
|
|
785
|
+
/// Returns whether `through` named a history item.
|
|
786
|
+
pub fn absorb_provider_compaction(
|
|
787
|
+
&mut self,
|
|
788
|
+
through: ItemId,
|
|
789
|
+
replay: serde_json::Value,
|
|
790
|
+
summary_tokens: u32,
|
|
791
|
+
) -> bool {
|
|
792
|
+
let history = &self.partitions.history;
|
|
793
|
+
let Some(position) = history.tags().iter().position(|tag| tag.id == through) else {
|
|
794
|
+
return false;
|
|
795
|
+
};
|
|
796
|
+
let end = super::units::unit_boundaries(history.messages())
|
|
797
|
+
.into_iter()
|
|
798
|
+
.find(|unit| unit.contains(&position))
|
|
799
|
+
.map_or(position + 1, |unit| unit.end);
|
|
800
|
+
let covered_tokens: u32 = (0..end)
|
|
801
|
+
.map(|index| history.measured_tokens(index, &self.engine))
|
|
802
|
+
.sum();
|
|
803
|
+
let retained = history.token_count().saturating_sub(covered_tokens);
|
|
804
|
+
let covered: std::collections::BTreeSet<usize> = (0..end).collect();
|
|
805
|
+
let rows = self.partitions.history.take_rows(&covered, retained);
|
|
806
|
+
for row in &rows {
|
|
807
|
+
let record = HistoryItemRecord::of(
|
|
808
|
+
row.tag,
|
|
809
|
+
row.measurement.tokens,
|
|
810
|
+
row.tag.fidelity,
|
|
811
|
+
Some(ItemEnd::Compacted),
|
|
812
|
+
);
|
|
813
|
+
self.retire_history_item(record);
|
|
814
|
+
}
|
|
815
|
+
self.last_item_id += 1;
|
|
816
|
+
let tag = ItemTag::new(
|
|
817
|
+
self.last_item_id,
|
|
818
|
+
ItemOrigin::ProviderSummary,
|
|
819
|
+
self.partitions.knowledge.turn,
|
|
820
|
+
);
|
|
821
|
+
let message = CoreMessage::assistant("[earlier conversation summarized by the provider]");
|
|
822
|
+
let tally = self.tally(ItemOrigin::ProviderSummary);
|
|
823
|
+
tally.items += 1;
|
|
824
|
+
tally.tokens += u64::from(summary_tokens);
|
|
825
|
+
self.partitions.history.prepend_row(super::partitions::PartitionRow {
|
|
826
|
+
tag,
|
|
827
|
+
measurement: super::measurement::TokenMeasurement::for_message(&message, summary_tokens),
|
|
828
|
+
message,
|
|
829
|
+
});
|
|
830
|
+
self.keep_item_replay(tag.id, replay);
|
|
831
|
+
self.prune_orphaned_handles();
|
|
832
|
+
self.prune_item_replays();
|
|
833
|
+
self.reset_collapse_generation();
|
|
834
|
+
self.sweep_knowledge_at_boundary();
|
|
835
|
+
self.frozen_history_len = self.partitions.history.len();
|
|
836
|
+
true
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
/// Plan task 5.1 · the provider cleared these tool results server-side: render them as
|
|
840
|
+
/// handles, as the model now sees them.
|
|
841
|
+
pub fn absorb_cleared_tool_results<'a>(&mut self, call_ids: impl IntoIterator<Item = &'a str>) {
|
|
842
|
+
let cleared: std::collections::HashSet<&str> = call_ids.into_iter().collect();
|
|
843
|
+
for handle in self.handles.tool_result_handles_mut() {
|
|
844
|
+
if handle.source.as_deref().is_some_and(|source| cleared.contains(source))
|
|
845
|
+
&& matches!(handle.residency, Residency::Resident)
|
|
846
|
+
{
|
|
847
|
+
handle.residency = Residency::Collapsed;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
/// Keep `replay` with item `id`, counting what it adds to a request.
|
|
853
|
+
pub(crate) fn keep_item_replay(&mut self, id: ItemId, replay: serde_json::Value) {
|
|
854
|
+
let tokens = self.engine.count(&replay.to_string());
|
|
855
|
+
self.item_replays.insert(id, (replay, tokens));
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
/// Tokens the replay of every item still in history adds to a request.
|
|
859
|
+
fn replay_tokens(&self) -> u32 {
|
|
860
|
+
self.item_replays.values().map(|(_, tokens)| *tokens).sum()
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
/// Drop replay state whose item left history.
|
|
864
|
+
fn prune_item_replays(&mut self) {
|
|
865
|
+
if self.item_replays.is_empty() {
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
let live: std::collections::HashSet<ItemId> =
|
|
869
|
+
self.partitions.history.tags().iter().map(|tag| tag.id).collect();
|
|
870
|
+
self.item_replays.retain(|id, _| live.contains(id));
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
/// Append `msg` to history after the tool results the last assistant turn still waits for.
|
|
874
|
+
/// Used for content an effect delivers mid-batch (a memory hit that resolves before a sibling
|
|
875
|
+
/// tool): placed now, it would split the batch's results, which a provider rejects.
|
|
876
|
+
pub fn push_history_after_tool_results(&mut self, msg: CoreMessage, tokens: u32) {
|
|
877
|
+
if self.awaits_tool_results() {
|
|
878
|
+
self.held_history.push((msg, tokens));
|
|
879
|
+
} else {
|
|
880
|
+
self.push_history(msg, tokens);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
/// Append whatever is still held, whether or not the batch completed. Called before a provider
|
|
885
|
+
/// call, so held content is never lost to a batch whose results never all arrived.
|
|
886
|
+
pub fn release_held_history(&mut self) {
|
|
887
|
+
for (held, tokens) in std::mem::take(&mut self.held_history) {
|
|
888
|
+
self.admit_history(held, tokens);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
|
|
685
892
|
pub fn push_history(&mut self, msg: CoreMessage, tokens: u32) {
|
|
893
|
+
let is_tool = msg.role == crate::types::message::Role::Tool;
|
|
894
|
+
self.admit_history(msg, tokens);
|
|
895
|
+
if is_tool && !self.held_history.is_empty() && !self.awaits_tool_results() {
|
|
896
|
+
for (held, tokens) in std::mem::take(&mut self.held_history) {
|
|
897
|
+
self.admit_history(held, tokens);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
/// Whether the last assistant message in history asked for a call whose result is not in
|
|
903
|
+
/// history yet.
|
|
904
|
+
fn awaits_tool_results(&self) -> bool {
|
|
905
|
+
let mut answered = std::collections::HashSet::new();
|
|
906
|
+
for message in self.partitions.history.messages().iter().rev() {
|
|
907
|
+
match message.role {
|
|
908
|
+
crate::types::message::Role::Tool => {
|
|
909
|
+
if let Content::Parts(parts) = &message.content {
|
|
910
|
+
for part in parts {
|
|
911
|
+
if let ContentPart::ToolResult { call_id, .. } = part {
|
|
912
|
+
answered.insert(call_id.as_str());
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
crate::types::message::Role::Assistant => {
|
|
918
|
+
return message
|
|
919
|
+
.tool_calls
|
|
920
|
+
.iter()
|
|
921
|
+
.any(|call| !answered.contains(call.id.as_str()));
|
|
922
|
+
}
|
|
923
|
+
_ => return false,
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
false
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
fn admit_history(&mut self, msg: CoreMessage, tokens: u32) {
|
|
686
930
|
self.knowledge_reference_step = self.knowledge_reference_step.saturating_add(1);
|
|
687
931
|
self.partitions
|
|
688
932
|
.knowledge
|
|
@@ -715,11 +959,18 @@ impl ContextManager {
|
|
|
715
959
|
let tally = self.tally(tag.origin);
|
|
716
960
|
tally.items += 1;
|
|
717
961
|
tally.tokens += u64::from(tokens);
|
|
962
|
+
if tag.origin == ItemOrigin::Assistant {
|
|
963
|
+
if let Some(replay) = self.pending_assistant_replay.take() {
|
|
964
|
+
self.keep_item_replay(tag.id, replay);
|
|
965
|
+
}
|
|
966
|
+
}
|
|
718
967
|
self.partitions.history.push_tagged(msg, tokens, tag);
|
|
719
968
|
}
|
|
720
969
|
|
|
721
970
|
/// Drop history from `len` on (a rolled-back turn); its items leave as removed.
|
|
722
971
|
pub fn truncate_history(&mut self, len: usize) {
|
|
972
|
+
// Held messages belong to the turn being rolled back.
|
|
973
|
+
self.held_history.clear();
|
|
723
974
|
for index in len..self.partitions.history.len() {
|
|
724
975
|
let tag = self.partitions.history.tag(index);
|
|
725
976
|
let tokens = self.partitions.history.measured_tokens(index, &self.engine);
|
|
@@ -732,6 +983,7 @@ impl ContextManager {
|
|
|
732
983
|
));
|
|
733
984
|
}
|
|
734
985
|
self.partitions.history.truncate(len);
|
|
986
|
+
self.prune_item_replays();
|
|
735
987
|
}
|
|
736
988
|
|
|
737
989
|
fn retire_history_item(&mut self, record: HistoryItemRecord) {
|
|
@@ -1754,6 +2006,102 @@ mod tests {
|
|
|
1754
2006
|
assert_eq!(metrics.history_items.last().unwrap().id, (HISTORY_ITEM_DETAIL_CAP + 10) as u64);
|
|
1755
2007
|
}
|
|
1756
2008
|
|
|
2009
|
+
#[test]
|
|
2010
|
+
fn the_estimate_calibrates_toward_what_the_provider_counts() {
|
|
2011
|
+
let mut mgr = ContextManager::new(100_000);
|
|
2012
|
+
assert_eq!(mgr.note_request_estimate(600), 600, "uncalibrated before any count");
|
|
2013
|
+
mgr.set_observed_prompt_tokens(810);
|
|
2014
|
+
assert_eq!(mgr.note_request_estimate(1_200), 1_410, "one sample: its offset");
|
|
2015
|
+
mgr.set_observed_prompt_tokens(1_470);
|
|
2016
|
+
// A fixed overhead plus a proportional gap (count = 1.1 x estimate + 150) is fitted
|
|
2017
|
+
// exactly once there are two sizes.
|
|
2018
|
+
for raw in [2_000u32, 2_800] {
|
|
2019
|
+
mgr.note_request_estimate(raw);
|
|
2020
|
+
mgr.set_observed_prompt_tokens(raw * 11 / 10 + 150);
|
|
2021
|
+
}
|
|
2022
|
+
assert_eq!(mgr.note_request_estimate(3_600), 4_110);
|
|
2023
|
+
// An observation with no estimate pending (a restore, a test) adds no sample.
|
|
2024
|
+
let samples = mgr.estimate_samples.len();
|
|
2025
|
+
mgr.last_request_estimate = 0;
|
|
2026
|
+
mgr.set_observed_prompt_tokens(50);
|
|
2027
|
+
assert_eq!(mgr.estimate_samples.len(), samples);
|
|
2028
|
+
// Only the most recent samples count.
|
|
2029
|
+
for _ in 0..ESTIMATE_CALIBRATION_SAMPLES {
|
|
2030
|
+
mgr.note_request_estimate(1_000);
|
|
2031
|
+
mgr.set_observed_prompt_tokens(1_000);
|
|
2032
|
+
}
|
|
2033
|
+
assert_eq!(mgr.note_request_estimate(5_000), 5_000);
|
|
2034
|
+
}
|
|
2035
|
+
|
|
2036
|
+
#[test]
|
|
2037
|
+
fn replay_sent_back_with_a_turn_counts_toward_the_estimate() {
|
|
2038
|
+
let mut mgr = ContextManager::new(100_000);
|
|
2039
|
+
mgr.push_history(CoreMessage::user("question"), 5);
|
|
2040
|
+
let before = (mgr.render().estimated_tokens, mgr.rho());
|
|
2041
|
+
mgr.pending_assistant_replay =
|
|
2042
|
+
Some(serde_json::json!({ "reasoning_content": "step ".repeat(400) }));
|
|
2043
|
+
mgr.push_history(CoreMessage::assistant("answer"), 5);
|
|
2044
|
+
let (estimate, rho) = (mgr.render().estimated_tokens, mgr.rho());
|
|
2045
|
+
assert!(estimate >= before.0 + 5 + 300, "{estimate} vs {}", before.0);
|
|
2046
|
+
assert!(rho > before.1);
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2049
|
+
#[test]
|
|
2050
|
+
fn calibration_raises_pressure_but_never_lowers_it() {
|
|
2051
|
+
let mut mgr = ContextManager::new(1_000);
|
|
2052
|
+
mgr.push_history(CoreMessage::user("x".repeat(400)), 400);
|
|
2053
|
+
let raw = mgr.pressure.pressure(&mgr.partitions, &mgr.engine, None);
|
|
2054
|
+
mgr.estimate_samples = [(1_000, 500)].into();
|
|
2055
|
+
assert!((mgr.rho() - raw).abs() < 1e-9, "a low count does not delay compaction");
|
|
2056
|
+
mgr.estimate_samples = [(1_000, 1_200)].into();
|
|
2057
|
+
assert!((mgr.rho() - (raw + 0.2)).abs() < 1e-3, "an undercount raises pressure");
|
|
2058
|
+
}
|
|
2059
|
+
|
|
2060
|
+
#[test]
|
|
2061
|
+
fn a_provider_summary_replaces_the_items_it_covered() {
|
|
2062
|
+
use crate::types::message::ToolCall;
|
|
2063
|
+
let mut mgr = ContextManager::new(100_000);
|
|
2064
|
+
mgr.push_history(CoreMessage::user("question"), 50);
|
|
2065
|
+
let mut call = CoreMessage::assistant("reading");
|
|
2066
|
+
call.tool_calls = vec![ToolCall {
|
|
2067
|
+
id: "c1".into(),
|
|
2068
|
+
name: "read".into(),
|
|
2069
|
+
arguments: serde_json::json!({}),
|
|
2070
|
+
}];
|
|
2071
|
+
mgr.push_history(call, 20);
|
|
2072
|
+
mgr.push_history(tool_result_msg("c1", &"body ".repeat(200)), 400);
|
|
2073
|
+
mgr.push_history(CoreMessage::user("next question"), 10);
|
|
2074
|
+
let (assistant, tool) = (mgr.partitions.history.tag(1).id, mgr.partitions.history.tag(2).id);
|
|
2075
|
+
|
|
2076
|
+
let block = serde_json::json!({ "protocol": "anthropic-messages", "native_blocks": [{ "type": "compaction" }] });
|
|
2077
|
+
// Covering through the call extends to its result: a transaction is never split.
|
|
2078
|
+
assert!(mgr.absorb_provider_compaction(assistant, block.clone(), 30));
|
|
2079
|
+
let tags = mgr.partitions.history.tags();
|
|
2080
|
+
assert_eq!(tags[0].origin, ItemOrigin::ProviderSummary);
|
|
2081
|
+
assert_eq!(tags.len(), 2, "summary + the uncovered question");
|
|
2082
|
+
assert!(tags.iter().all(|tag| tag.id != tool));
|
|
2083
|
+
assert_eq!(mgr.partitions.history.token_count(), 30 + 10);
|
|
2084
|
+
assert!(mgr.handles.residency_for_source("c1").is_none(), "the covered result's handle left");
|
|
2085
|
+
|
|
2086
|
+
let rendered = mgr.render();
|
|
2087
|
+
let summary = rendered.turn_items.iter().position(|id| *id == tags[0].id).unwrap();
|
|
2088
|
+
assert_eq!(rendered.turn_replays[summary], Some(block));
|
|
2089
|
+
let ends: Vec<_> = mgr.lifecycle_metrics().history_items.iter().map(|item| item.end).collect();
|
|
2090
|
+
assert_eq!(ends.iter().filter(|end| **end == Some(ItemEnd::Compacted)).count(), 3);
|
|
2091
|
+
assert!(!mgr.absorb_provider_compaction(9_999, serde_json::json!({}), 1), "unknown item");
|
|
2092
|
+
}
|
|
2093
|
+
|
|
2094
|
+
#[test]
|
|
2095
|
+
fn tool_results_the_provider_cleared_render_as_handles() {
|
|
2096
|
+
let mut mgr = ContextManager::new(100_000);
|
|
2097
|
+
mgr.push_history(tool_result_msg("c1", "first"), 5);
|
|
2098
|
+
mgr.push_history(tool_result_msg("c2", "second"), 5);
|
|
2099
|
+
mgr.absorb_cleared_tool_results(["c1"]);
|
|
2100
|
+
assert_eq!(mgr.handles.residency_for_source("c1"), Some(&Residency::Collapsed));
|
|
2101
|
+
assert_eq!(mgr.handles.residency_for_source("c2"), Some(&Residency::Resident));
|
|
2102
|
+
assert_eq!(mgr.history_fidelity(0), crate::context::item::Fidelity::Handle);
|
|
2103
|
+
}
|
|
2104
|
+
|
|
1757
2105
|
#[test]
|
|
1758
2106
|
fn history_messages_are_items_whose_identity_survives_renewal() {
|
|
1759
2107
|
let mut mgr = ContextManager::new(100_000);
|