cc-transcript 14.31.0__tar.gz → 14.32.0__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.
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/PKG-INFO +1 -1
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/pyproject.toml +1 -1
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/snapshot.rs +193 -40
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/snapshot_codec.rs +42 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/snapshot_labels.rs +23 -1
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/snapshot_prepared_service.rs +27 -29
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/snapshot_projection.rs +27 -6
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/snapshot_root_warm.rs +59 -3
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/Cargo.lock +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/Cargo.toml +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/LICENSE +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/README.md +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/__init__.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/__init__.pyi +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/_native.pyi +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/activity.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/activity_probe.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/builders.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/codex.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/command.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/context.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/corrections.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/cost.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/decision_store.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/decisions.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/discovery.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/disktruth.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/evidence.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/extract/__init__.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/extract/correct.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/facts.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/filterspec.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/heartbeats.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/ids.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/judge/__init__.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/judge/llm.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/judge/similar.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/judge/verdicts.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/ledger.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/literals.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/mining/__init__.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/mining/candidates.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/mining/confidence.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/mining/engine.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/mining/formats.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/mining/sampling.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/mining/signals.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/mining/sourcekind.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/mining/spec.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/mining/store.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/models.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/nlp.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/notifications.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/parser.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/py.typed +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/query.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/render.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/sentiment/__init__.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/sentiment/buckets.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/sentiment/data/afinn-en-165.tsv +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/sentiment/data/domain_overrides.tsv +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/sentiment/data/en-ewt.udpipe +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/sentiment/engine.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/sentiment/lexicon.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/sentiment/scorespec.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/snapshot_schema/config.schema.json +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/snapshot_schema/context.schema.json +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/snapshot_schema/request.schema.json +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/snapshot_schema/response.schema.json +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/snapshot_schema/tool_registry.schema.json +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/snapshots.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/synthetic.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/tools.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/cc_transcript/watch.py +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/cli/Cargo.toml +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/cli/src/commands/blame.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/cli/src/commands/corpus.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/cli/src/commands/corrections.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/cli/src/commands/digest.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/cli/src/commands/facts.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/cli/src/commands/grep.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/cli/src/commands/list.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/cli/src/commands/mod.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/cli/src/commands/scratchpad.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/cli/src/commands/show.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/cli/src/commands/slice.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/cli/src/commands/stats.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/cli/src/commands/watch.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/cli/src/lib.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/cli/src/main.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/cli/src/output.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/cli/src/target.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/cli/src/timearg.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/Cargo.toml +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/benches/parse.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/benches/render.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/benches/toolcall.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/activity.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/actor.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/blame.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/buckets.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/codex/discovery.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/codex/lower.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/codex/mod.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/codex/parse.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/codex/probe.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/codex/protocol.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/codex/types.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/command.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/context.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/corrections.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/cost.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/discovery.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/facts.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/feedback.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/filter.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/gateway.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/ids.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/judge.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/lib.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/literals/command.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/literals/corrections.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/literals/feedback.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/literals/mining.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/literals/mod.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/literals/protocol.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/notifications.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/parse.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/protocol.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/pystr.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/query.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/render.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/rng.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/scan.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/scan_grep.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/scan_regressions.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/schema.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/snapshot_activity.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/snapshot_codex_append.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/snapshot_memory.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/snapshot_owned.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/snapshot_prepared.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/snapshot_prepared_disk.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/snapshot_regressions.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/snapshot_text.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/sqlite.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/toolcall.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/types.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/value.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/watch.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/Cargo.toml +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/build.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/data/command_prefix_pins.tsv +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/actor_bridge.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/bin/stub_gen.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/codex.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/command.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/context.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/corrections.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/discovery.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/feedback.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/judge.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/lexicon.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/lib.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/mining.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/nlp.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/python.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/render.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/score.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/snapshot_decode.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/snapshots.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/sqlite.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/toolcall.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/views/attachment.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/views/blocks.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/views/command.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/views/convert.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/views/dunder.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/views/events.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/views/meta.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/views/mod.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/views/print.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/views/store.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/views/system.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/views/toolcall.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/views/toolresult.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/views/transcript.rs +0 -0
- {cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/py/src/watch.rs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "cc-transcript"
|
|
3
|
-
version = "14.
|
|
3
|
+
version = "14.32.0" # informational — releases stamp the version from the git tag
|
|
4
4
|
description = "Grep every Claude Code session you've ever run."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "PolyForm-Noncommercial-1.0.0"
|
|
@@ -423,6 +423,7 @@ struct Waiter {
|
|
|
423
423
|
used_source_bytes: usize,
|
|
424
424
|
used_events: usize,
|
|
425
425
|
stage: Option<Arc<ClassifierSlot>>,
|
|
426
|
+
windowed: bool,
|
|
426
427
|
busy: bool,
|
|
427
428
|
}
|
|
428
429
|
|
|
@@ -688,7 +689,7 @@ struct PreparedQueryCursor {
|
|
|
688
689
|
graph_id: String,
|
|
689
690
|
query: Value,
|
|
690
691
|
pending: Option<PendingPreparedSource>,
|
|
691
|
-
|
|
692
|
+
input_records: Option<VecDeque<String>>,
|
|
692
693
|
next: usize,
|
|
693
694
|
page_output_bytes: usize,
|
|
694
695
|
remaining: WorkLimits,
|
|
@@ -763,7 +764,7 @@ struct GraphCursor {
|
|
|
763
764
|
prepared: bool,
|
|
764
765
|
root_checked: bool,
|
|
765
766
|
projection_at: usize,
|
|
766
|
-
|
|
767
|
+
pending_records: VecDeque<(usize, String)>,
|
|
767
768
|
published_members: Vec<usize>,
|
|
768
769
|
expires: u64,
|
|
769
770
|
accounted: usize,
|
|
@@ -2507,7 +2508,10 @@ impl NativeStore {
|
|
|
2507
2508
|
.values()
|
|
2508
2509
|
.map(|cursor| {
|
|
2509
2510
|
size_of::<PreparedQueryCursor>()
|
|
2510
|
-
+ cursor
|
|
2511
|
+
+ cursor
|
|
2512
|
+
.input_records
|
|
2513
|
+
.as_ref()
|
|
2514
|
+
.map_or(0, |records| records.iter().map(String::capacity).sum())
|
|
2511
2515
|
+ crate::snapshot_memory::value_charge(&cursor.query).owned_capacity_bytes
|
|
2512
2516
|
})
|
|
2513
2517
|
.sum::<usize>()
|
|
@@ -4154,6 +4158,7 @@ impl NativeStore {
|
|
|
4154
4158
|
used_source_bytes: 0,
|
|
4155
4159
|
used_events: 0,
|
|
4156
4160
|
stage: None,
|
|
4161
|
+
windowed: window.is_some(),
|
|
4157
4162
|
busy: false,
|
|
4158
4163
|
};
|
|
4159
4164
|
state.waiters.insert(cursor.clone(), waiter.clone());
|
|
@@ -4409,6 +4414,14 @@ impl NativeStore {
|
|
|
4409
4414
|
if let Some(snapshot) = &load.result {
|
|
4410
4415
|
let snapshot = Arc::clone(snapshot);
|
|
4411
4416
|
drop(load);
|
|
4417
|
+
if waiter.windowed && snapshot.provider == Provider::Codex {
|
|
4418
|
+
self.state
|
|
4419
|
+
.lock()
|
|
4420
|
+
.expect("snapshot state")
|
|
4421
|
+
.waiters
|
|
4422
|
+
.remove(token);
|
|
4423
|
+
return Err(invalid("tail_bytes requires a Claude source"));
|
|
4424
|
+
}
|
|
4412
4425
|
let mut state = self.state.lock().expect("snapshot state");
|
|
4413
4426
|
if !state
|
|
4414
4427
|
.latest
|
|
@@ -5039,7 +5052,7 @@ impl NativeStore {
|
|
|
5039
5052
|
depth: 1,
|
|
5040
5053
|
});
|
|
5041
5054
|
}
|
|
5042
|
-
let identity = root.stamp.identity;
|
|
5055
|
+
let identity = root.stamp.identity.file();
|
|
5043
5056
|
let graph = GraphCursor {
|
|
5044
5057
|
claimant: str_field(context, "claimant")?.to_owned(),
|
|
5045
5058
|
context: context.clone(),
|
|
@@ -5061,7 +5074,7 @@ impl NativeStore {
|
|
|
5061
5074
|
prepared: false,
|
|
5062
5075
|
root_checked: false,
|
|
5063
5076
|
projection_at: 0,
|
|
5064
|
-
|
|
5077
|
+
pending_records: VecDeque::new(),
|
|
5065
5078
|
published_members: Vec::new(),
|
|
5066
5079
|
expires: (now_ms() + self.config.ttl).min(bounds.deadline_unix_ms),
|
|
5067
5080
|
accounted: 0,
|
|
@@ -5142,9 +5155,10 @@ impl NativeStore {
|
|
|
5142
5155
|
.sum::<usize>()
|
|
5143
5156
|
+ graph.tasks.capacity() * size_of::<GraphTask>()
|
|
5144
5157
|
+ graph
|
|
5145
|
-
.
|
|
5146
|
-
.
|
|
5147
|
-
.
|
|
5158
|
+
.pending_records
|
|
5159
|
+
.iter()
|
|
5160
|
+
.map(|(_, record)| record.capacity())
|
|
5161
|
+
.sum::<usize>()
|
|
5148
5162
|
+ graph.listing.as_ref().map_or(0, |listing| {
|
|
5149
5163
|
listing
|
|
5150
5164
|
.children
|
|
@@ -5199,7 +5213,7 @@ impl NativeStore {
|
|
|
5199
5213
|
&graph.context,
|
|
5200
5214
|
graph.remaining.deadline_unix_ms,
|
|
5201
5215
|
)?;
|
|
5202
|
-
let identity = snapshot.stamp.identity;
|
|
5216
|
+
let identity = snapshot.stamp.identity.file();
|
|
5203
5217
|
if !graph.seen.insert(identity)
|
|
5204
5218
|
&& graph.request["query"]["kind"].as_str() != Some("direct_sidechains")
|
|
5205
5219
|
{
|
|
@@ -5556,7 +5570,7 @@ impl NativeStore {
|
|
|
5556
5570
|
let mut output_bytes = 128usize;
|
|
5557
5571
|
let page_limit = self.config.page_items.min(graph.remaining.max_items);
|
|
5558
5572
|
let mut projected = 0usize;
|
|
5559
|
-
while graph.projection_at < total || graph.
|
|
5573
|
+
while graph.projection_at < total || !graph.pending_records.is_empty() {
|
|
5560
5574
|
cancel.check(graph.remaining.deadline_unix_ms)?;
|
|
5561
5575
|
if boolean && projected >= self.config.page_items {
|
|
5562
5576
|
return Ok(GraphYield::Pending(Value::new_null()));
|
|
@@ -5564,7 +5578,7 @@ impl NativeStore {
|
|
|
5564
5578
|
if records.len() >= page_limit {
|
|
5565
5579
|
break;
|
|
5566
5580
|
}
|
|
5567
|
-
let (index, record) = if let Some(pending) = graph.
|
|
5581
|
+
let (index, record) = if let Some(pending) = graph.pending_records.pop_front() {
|
|
5568
5582
|
pending
|
|
5569
5583
|
} else {
|
|
5570
5584
|
let position = if reverse {
|
|
@@ -5597,27 +5611,27 @@ impl NativeStore {
|
|
|
5597
5611
|
let mut bounds = graph.remaining;
|
|
5598
5612
|
bounds.max_items = 1;
|
|
5599
5613
|
bounds.max_output_bytes = bounds.max_output_bytes.min(MAX_DATA_BYTES);
|
|
5600
|
-
let projection = crate::snapshot_projection::project(
|
|
5601
|
-
&node.snapshot,
|
|
5602
|
-
&request,
|
|
5603
|
-
&bounds,
|
|
5604
|
-
cancel,
|
|
5605
|
-
0,
|
|
5606
|
-
)?;
|
|
5607
|
-
graph.remaining.max_read_bytes = graph
|
|
5608
|
-
.remaining
|
|
5609
|
-
.max_read_bytes
|
|
5610
|
-
.saturating_sub(projection.read_bytes);
|
|
5611
|
-
graph.remaining.max_events =
|
|
5612
|
-
graph.remaining.max_events.saturating_sub(projection.events);
|
|
5613
|
-
if !projection.complete {
|
|
5614
|
-
return Err(SnapshotError::new(
|
|
5615
|
-
Status::Incomplete,
|
|
5616
|
-
"graph member projection incomplete",
|
|
5617
|
-
));
|
|
5618
|
-
}
|
|
5619
|
-
graph.projection_at += 1;
|
|
5620
5614
|
if boolean {
|
|
5615
|
+
let projection = crate::snapshot_projection::project(
|
|
5616
|
+
&node.snapshot,
|
|
5617
|
+
&request,
|
|
5618
|
+
&bounds,
|
|
5619
|
+
cancel,
|
|
5620
|
+
0,
|
|
5621
|
+
)?;
|
|
5622
|
+
graph.remaining.max_read_bytes = graph
|
|
5623
|
+
.remaining
|
|
5624
|
+
.max_read_bytes
|
|
5625
|
+
.saturating_sub(projection.read_bytes);
|
|
5626
|
+
graph.remaining.max_events =
|
|
5627
|
+
graph.remaining.max_events.saturating_sub(projection.events);
|
|
5628
|
+
if !projection.complete {
|
|
5629
|
+
return Err(SnapshotError::new(
|
|
5630
|
+
Status::Incomplete,
|
|
5631
|
+
"graph member projection incomplete",
|
|
5632
|
+
));
|
|
5633
|
+
}
|
|
5634
|
+
graph.projection_at += 1;
|
|
5621
5635
|
projected += 1;
|
|
5622
5636
|
if projection.data["value"].as_bool() == Some(true) {
|
|
5623
5637
|
return Ok(GraphYield::Complete(projection.data));
|
|
@@ -5627,20 +5641,29 @@ impl NativeStore {
|
|
|
5627
5641
|
}
|
|
5628
5642
|
continue;
|
|
5629
5643
|
}
|
|
5630
|
-
(
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5644
|
+
let (member_records, read_bytes, events) =
|
|
5645
|
+
crate::snapshot_projection::predicate_input_records(
|
|
5646
|
+
&node.snapshot,
|
|
5647
|
+
&request["view"]["selectors"],
|
|
5648
|
+
&bounds,
|
|
5649
|
+
cancel,
|
|
5650
|
+
)?;
|
|
5651
|
+
graph.remaining.max_read_bytes =
|
|
5652
|
+
graph.remaining.max_read_bytes.saturating_sub(read_bytes);
|
|
5653
|
+
graph.remaining.max_events = graph.remaining.max_events.saturating_sub(events);
|
|
5654
|
+
graph.projection_at += 1;
|
|
5655
|
+
let mut member_records =
|
|
5656
|
+
member_records.into_iter().map(|record| (index, record));
|
|
5657
|
+
let first = member_records.next().expect("predicate member record");
|
|
5658
|
+
graph.pending_records.extend(member_records);
|
|
5659
|
+
first
|
|
5637
5660
|
}
|
|
5638
5661
|
};
|
|
5639
5662
|
let record_bytes = encoded_size(&json!(&record), MAX_DATA_BYTES)?;
|
|
5640
5663
|
if output_bytes.saturating_add(record_bytes)
|
|
5641
5664
|
> graph.remaining.max_output_bytes.min(MAX_DATA_BYTES)
|
|
5642
5665
|
{
|
|
5643
|
-
graph.
|
|
5666
|
+
graph.pending_records.push_front((index, record));
|
|
5644
5667
|
if records.is_empty() {
|
|
5645
5668
|
return Err(SnapshotError::new(
|
|
5646
5669
|
Status::OutputLimit,
|
|
@@ -5664,7 +5687,7 @@ impl NativeStore {
|
|
|
5664
5687
|
.remaining
|
|
5665
5688
|
.max_items
|
|
5666
5689
|
.saturating_sub(data["records_json"].as_array().expect("records").len());
|
|
5667
|
-
if graph.projection_at >= total && graph.
|
|
5690
|
+
if graph.projection_at >= total && graph.pending_records.is_empty() {
|
|
5668
5691
|
Ok(GraphYield::Complete(data))
|
|
5669
5692
|
} else if graph.remaining.max_items == 0 {
|
|
5670
5693
|
Err(SnapshotError::new(
|
|
@@ -8235,6 +8258,64 @@ mod tests {
|
|
|
8235
8258
|
&Cancellation::default(),
|
|
8236
8259
|
);
|
|
8237
8260
|
assert_eq!(zero["status"].as_str(), Some("invalid_request"));
|
|
8261
|
+
let size = std::fs::metadata(&codex.path).unwrap().len();
|
|
8262
|
+
for tail_bytes in [size, size - 1, 1024 * 1024] {
|
|
8263
|
+
let covered = finish(
|
|
8264
|
+
&store,
|
|
8265
|
+
store.request(
|
|
8266
|
+
&windowed_acquire(&codex.path, tail_bytes),
|
|
8267
|
+
&owner,
|
|
8268
|
+
&Cancellation::default(),
|
|
8269
|
+
),
|
|
8270
|
+
&owner,
|
|
8271
|
+
);
|
|
8272
|
+
assert_eq!(
|
|
8273
|
+
covered["reason"].as_str(),
|
|
8274
|
+
Some("tail_bytes requires a Claude source"),
|
|
8275
|
+
"{tail_bytes}: {covered:?}"
|
|
8276
|
+
);
|
|
8277
|
+
}
|
|
8278
|
+
let whole = finish(
|
|
8279
|
+
&store,
|
|
8280
|
+
store.request(&acquire(&codex.path), &owner, &Cancellation::default()),
|
|
8281
|
+
&owner,
|
|
8282
|
+
);
|
|
8283
|
+
assert_eq!(whole["status"].as_str(), Some("ok"), "{whole:?}");
|
|
8284
|
+
let cached = finish(
|
|
8285
|
+
&store,
|
|
8286
|
+
store.request(
|
|
8287
|
+
&windowed_acquire(&codex.path, 1024 * 1024),
|
|
8288
|
+
&owner,
|
|
8289
|
+
&Cancellation::default(),
|
|
8290
|
+
),
|
|
8291
|
+
&owner,
|
|
8292
|
+
);
|
|
8293
|
+
assert_eq!(cached["status"].as_str(), Some("invalid_request"));
|
|
8294
|
+
assert_eq!(
|
|
8295
|
+
cached["reason"].as_str(),
|
|
8296
|
+
Some("tail_bytes requires a Claude source")
|
|
8297
|
+
);
|
|
8298
|
+
}
|
|
8299
|
+
|
|
8300
|
+
#[test]
|
|
8301
|
+
fn windowed_root_attached_to_itself_is_not_its_own_child() {
|
|
8302
|
+
let source = Source::new(&users(0..200));
|
|
8303
|
+
let store = windowed_store();
|
|
8304
|
+
let owner = context("a");
|
|
8305
|
+
let root = windowed(&store, &source.path, 4096, &owner);
|
|
8306
|
+
let (_, _, first) = expected_window(&source.path, 4096);
|
|
8307
|
+
assert!(first > 0);
|
|
8308
|
+
let records = graph_records(
|
|
8309
|
+
&store,
|
|
8310
|
+
&graph_request(
|
|
8311
|
+
&root,
|
|
8312
|
+
json!({"kind":"sidechain_membership","order":"forward"}),
|
|
8313
|
+
vec![source.path.to_string_lossy().into_owned()],
|
|
8314
|
+
json!([]),
|
|
8315
|
+
),
|
|
8316
|
+
&owner,
|
|
8317
|
+
);
|
|
8318
|
+
assert!(records.is_empty(), "{records:?}");
|
|
8238
8319
|
}
|
|
8239
8320
|
|
|
8240
8321
|
#[test]
|
|
@@ -9183,6 +9264,78 @@ mod tests {
|
|
|
9183
9264
|
assert_eq!(after[15], after_first[15]);
|
|
9184
9265
|
}
|
|
9185
9266
|
|
|
9267
|
+
#[test]
|
|
9268
|
+
fn deep_predicate_inputs_split_a_window_over_the_record_bound() {
|
|
9269
|
+
let commands: Vec<String> = (0..48)
|
|
9270
|
+
.map(|index| format!("echo {index:02} {}", "x".repeat(32 * 1024)))
|
|
9271
|
+
.collect();
|
|
9272
|
+
let tools: String = commands
|
|
9273
|
+
.iter()
|
|
9274
|
+
.enumerate()
|
|
9275
|
+
.map(|(index, command)| format!(
|
|
9276
|
+
"{}\n",
|
|
9277
|
+
format_args!(r#"{{"type":"assistant","uuid":"tool-{index}","sessionId":"s","timestamp":"2026-01-02T03:04:06Z","message":{{"model":"test","content":[{{"type":"tool_use","id":"bash-{index}","name":"Bash","input":{{"command":"{command}"}}}}]}}}}"#)
|
|
9278
|
+
))
|
|
9279
|
+
.collect();
|
|
9280
|
+
let source = Source::new(&format!("{}\n{tools}", user("root")));
|
|
9281
|
+
let store = NativeStore::new(&json!({"max_read_bytes_per_step":4*1024*1024,"max_events_per_step":256,"max_entry_bytes":64*1024,"max_retained_bytes":64*1024*1024,"reserved_hook_accounted_bytes":4096,"max_leases":16,"reserved_hook_leases":1})).unwrap();
|
|
9282
|
+
let owner = context("a");
|
|
9283
|
+
let mut template = acquire(&source.path);
|
|
9284
|
+
template["limits"].insert("max_read_bytes", json!(64 * 1024 * 1024));
|
|
9285
|
+
template["limits"].insert("max_source_read_bytes", json!(64 * 1024 * 1024));
|
|
9286
|
+
template["limits"].insert("max_output_bytes", json!(16 * 1024 * 1024));
|
|
9287
|
+
let root = finish(
|
|
9288
|
+
&store,
|
|
9289
|
+
store.request(&template, &owner, &Cancellation::default()),
|
|
9290
|
+
&owner,
|
|
9291
|
+
);
|
|
9292
|
+
let commands_of = |records: &[String]| -> Vec<String> {
|
|
9293
|
+
assert!(records.len() > 1, "{} records", records.len());
|
|
9294
|
+
for record in records {
|
|
9295
|
+
assert!(record.len() <= crate::snapshot_codec::MAX_RECORD_BYTES);
|
|
9296
|
+
}
|
|
9297
|
+
crate::snapshot_codec::decode_predicate_inputs(
|
|
9298
|
+
records,
|
|
9299
|
+
crate::snapshot_codec::MAX_PAGE_BYTES,
|
|
9300
|
+
)
|
|
9301
|
+
.unwrap()
|
|
9302
|
+
.into_iter()
|
|
9303
|
+
.flat_map(|record| record.commands)
|
|
9304
|
+
.collect()
|
|
9305
|
+
};
|
|
9306
|
+
let pages = |mut page: Value| -> Vec<String> {
|
|
9307
|
+
let mut records = Vec::new();
|
|
9308
|
+
for _ in 0..64 {
|
|
9309
|
+
records.extend(
|
|
9310
|
+
page["data"]["records_json"]
|
|
9311
|
+
.as_array()
|
|
9312
|
+
.unwrap_or_else(|| panic!("{page:?}"))
|
|
9313
|
+
.iter()
|
|
9314
|
+
.map(|item| item.as_str().unwrap().to_owned()),
|
|
9315
|
+
);
|
|
9316
|
+
if page["status"].as_str() == Some("ok") {
|
|
9317
|
+
return records;
|
|
9318
|
+
}
|
|
9319
|
+
assert_eq!(page["status"].as_str(), Some("incomplete"), "{page:?}");
|
|
9320
|
+
page = store.request(&json!({"schema":SCHEMA,"id":"resume","operation":"resume","cursor":page["cursor"]}), &owner, &Cancellation::default());
|
|
9321
|
+
}
|
|
9322
|
+
panic!("deep predicate inputs did not finish");
|
|
9323
|
+
};
|
|
9324
|
+
let mut query = graph_request(
|
|
9325
|
+
&root,
|
|
9326
|
+
json!({"kind":"deep_predicate_inputs","order":"forward"}),
|
|
9327
|
+
Vec::new(),
|
|
9328
|
+
json!([]),
|
|
9329
|
+
);
|
|
9330
|
+
query["limits"] = template["limits"].clone();
|
|
9331
|
+
let lease = pages(store.request(&query, &owner, &Cancellation::default()));
|
|
9332
|
+
assert_eq!(commands_of(&lease), commands);
|
|
9333
|
+
let prepare = finish_prepared(&store, store.request(&json!({"schema":SCHEMA,"id":"prepare","operation":"prepare_graph","view":{"handle":handle(&root),"classifier":{"id":"native","version":"1"},"selectors":[],"attachments":[]},"thread_ids":[],"roots":[],"direct_paths":[],"deadline_unix_ms":template["deadline_unix_ms"],"limits":template["limits"]}), &owner, &Cancellation::default()), &owner);
|
|
9334
|
+
assert_eq!(prepare["status"].as_str(), Some("ok"), "{prepare:?}");
|
|
9335
|
+
let prepared = pages(store.request(&json!({"schema":SCHEMA,"id":"inputs","operation":"query_graph","handle":prepare["data"]["handle"],"selectors":[],"query":{"kind":"deep_predicate_inputs","order":"forward"},"deadline_unix_ms":template["deadline_unix_ms"],"limits":template["limits"]}), &owner, &Cancellation::default()));
|
|
9336
|
+
assert_eq!(commands_of(&prepared), commands);
|
|
9337
|
+
}
|
|
9338
|
+
|
|
9186
9339
|
#[test]
|
|
9187
9340
|
fn expired_prepared_query_reports_deadline_after_pruning() {
|
|
9188
9341
|
let source = Source::new(&format!("{}\n", user("root")));
|
|
@@ -144,6 +144,48 @@ pub struct PredicateInputsRecord {
|
|
|
144
144
|
pub skills: Vec<String>,
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
+
pub const PREDICATE_INPUT_CHUNK_BYTES: usize = 256 * 1024;
|
|
148
|
+
|
|
149
|
+
pub fn predicate_input_records(inputs: &sonic_rs::Value) -> Result<Vec<String>, SnapshotError> {
|
|
150
|
+
use sonic_rs::JsonContainerTrait;
|
|
151
|
+
|
|
152
|
+
let mut records = Vec::new();
|
|
153
|
+
let mut fields: [Vec<String>; 4] = Default::default();
|
|
154
|
+
let mut bytes = 0usize;
|
|
155
|
+
for (slot, name) in ["calls", "commands", "edited_files", "skills"]
|
|
156
|
+
.into_iter()
|
|
157
|
+
.enumerate()
|
|
158
|
+
{
|
|
159
|
+
for item in inputs[name]
|
|
160
|
+
.as_array()
|
|
161
|
+
.expect("predicate input field")
|
|
162
|
+
.iter()
|
|
163
|
+
{
|
|
164
|
+
let item = encode(item, MAX_RECORD_BYTES)?;
|
|
165
|
+
let cost = encoded_size(item.as_str(), MAX_RECORD_BYTES)? + 1;
|
|
166
|
+
if bytes > 0 && bytes + cost > PREDICATE_INPUT_CHUNK_BYTES {
|
|
167
|
+
records.push(predicate_input_record(&fields));
|
|
168
|
+
fields = Default::default();
|
|
169
|
+
bytes = 0;
|
|
170
|
+
}
|
|
171
|
+
bytes += cost;
|
|
172
|
+
fields[slot].push(item);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
records.push(predicate_input_record(&fields));
|
|
176
|
+
Ok(records)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
fn predicate_input_record([calls, commands, edited_files, skills]: &[Vec<String>; 4]) -> String {
|
|
180
|
+
format!(
|
|
181
|
+
r#"{{"calls":[{}],"commands":[{}],"edited_files":[{}],"skills":[{}]}}"#,
|
|
182
|
+
calls.join(","),
|
|
183
|
+
commands.join(","),
|
|
184
|
+
edited_files.join(","),
|
|
185
|
+
skills.join(",")
|
|
186
|
+
)
|
|
187
|
+
}
|
|
188
|
+
|
|
147
189
|
#[derive(Debug, Serialize, Deserialize)]
|
|
148
190
|
#[serde(deny_unknown_fields)]
|
|
149
191
|
pub struct SidechainRecord {
|
|
@@ -470,7 +470,7 @@ impl LabelPreparation {
|
|
|
470
470
|
session_id: self.source.session_id.clone(),
|
|
471
471
|
chunks: self.source.chunks.clone(),
|
|
472
472
|
activity: Arc::new(self.activity),
|
|
473
|
-
window_start:
|
|
473
|
+
window_start: self.source.window_start,
|
|
474
474
|
committed_bytes: self.source.committed_bytes,
|
|
475
475
|
provisional_tail: self.source.provisional_tail,
|
|
476
476
|
fence: self.source.fence.clone(),
|
|
@@ -1042,4 +1042,26 @@ mod tests {
|
|
|
1042
1042
|
"labels:execution"
|
|
1043
1043
|
);
|
|
1044
1044
|
}
|
|
1045
|
+
|
|
1046
|
+
#[test]
|
|
1047
|
+
fn finish_keeps_the_source_window_start() {
|
|
1048
|
+
let mut snapshot = source(vec![user(0, "prompt"), user(1, "later")]);
|
|
1049
|
+
{
|
|
1050
|
+
let windowed = Arc::get_mut(&mut snapshot).unwrap();
|
|
1051
|
+
windowed.window_start = 1000;
|
|
1052
|
+
windowed.stamp.identity.window_base = 1024;
|
|
1053
|
+
}
|
|
1054
|
+
let binding = binding("execution");
|
|
1055
|
+
let cancel = Cancellation::default();
|
|
1056
|
+
let mut stage =
|
|
1057
|
+
LabelPreparation::new(snapshot, binding.clone(), limits(), 8 * PAGE_BYTES, None)
|
|
1058
|
+
.unwrap();
|
|
1059
|
+
stage.next_page("page1".into(), &binding, &cancel).unwrap();
|
|
1060
|
+
assert!(stage
|
|
1061
|
+
.submit("page1", &[true, false], &binding, &cancel)
|
|
1062
|
+
.unwrap());
|
|
1063
|
+
let derived = stage.finish(&binding, &cancel).unwrap().0;
|
|
1064
|
+
assert_eq!(derived.window_start, 1000);
|
|
1065
|
+
assert_eq!(derived.stamp.identity.window_base, 1024);
|
|
1066
|
+
}
|
|
1045
1067
|
}
|
{cc_transcript-14.31.0 → cc_transcript-14.32.0}/rust/crates/core/src/snapshot_prepared_service.rs
RENAMED
|
@@ -1465,8 +1465,8 @@ impl NativeStore {
|
|
|
1465
1465
|
}
|
|
1466
1466
|
(graph.sources.clone(), graph.sidechain_dirs.clone())
|
|
1467
1467
|
};
|
|
1468
|
-
let inputs = cursor.
|
|
1469
|
-
let total = sources.len()
|
|
1468
|
+
let inputs = cursor.input_records.is_some();
|
|
1469
|
+
let total = sources.len();
|
|
1470
1470
|
let mut records = Vec::new();
|
|
1471
1471
|
let mut bytes = 128usize;
|
|
1472
1472
|
let mut steps = 0usize;
|
|
@@ -1483,27 +1483,30 @@ impl NativeStore {
|
|
|
1483
1483
|
"prepared query output budget exhausted",
|
|
1484
1484
|
));
|
|
1485
1485
|
}
|
|
1486
|
-
while cursor.next < total
|
|
1486
|
+
while (cursor.next < total
|
|
1487
|
+
|| cursor.input_records.as_ref().is_some_and(|records| !records.is_empty()))
|
|
1487
1488
|
&& steps < page_steps
|
|
1488
1489
|
&& uncached_steps < 8
|
|
1489
1490
|
&& (!inputs || records.len() < page_items)
|
|
1490
1491
|
{
|
|
1491
1492
|
cancel.check(cursor.remaining.deadline_unix_ms)?;
|
|
1492
|
-
if
|
|
1493
|
-
let record = cursor.root_record.as_ref().expect("input root record").clone();
|
|
1493
|
+
if let Some(record) = cursor.input_records.as_mut().and_then(VecDeque::pop_front) {
|
|
1494
1494
|
let record_bytes = encoded_size(&json!(&record), MAX_DATA_BYTES)? + 1;
|
|
1495
1495
|
if bytes + record_bytes > output_limit {
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1496
|
+
if records.is_empty() {
|
|
1497
|
+
return Err(SnapshotError::new(
|
|
1498
|
+
Status::OutputLimit,
|
|
1499
|
+
"prepared input record exceeds page bound",
|
|
1500
|
+
));
|
|
1501
|
+
}
|
|
1502
|
+
cursor.input_records.as_mut().expect("input records").push_front(record);
|
|
1503
|
+
break;
|
|
1500
1504
|
}
|
|
1501
1505
|
bytes += record_bytes;
|
|
1502
1506
|
records.push(record);
|
|
1503
|
-
cursor.next += 1;
|
|
1504
1507
|
continue;
|
|
1505
1508
|
}
|
|
1506
|
-
let source = &sources[cursor.next
|
|
1509
|
+
let source = &sources[cursor.next];
|
|
1507
1510
|
self.authority(context, Some(&source.path))?;
|
|
1508
1511
|
let metadata = std::fs::metadata(&source.path).map_err(io_error)?;
|
|
1509
1512
|
if SourceStamp::of(&metadata) != source.stamp {
|
|
@@ -1576,20 +1579,11 @@ impl NativeStore {
|
|
|
1576
1579
|
));
|
|
1577
1580
|
}
|
|
1578
1581
|
if inputs {
|
|
1579
|
-
|
|
1580
|
-
.
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
return Err(SnapshotError::new(
|
|
1585
|
-
Status::OutputLimit,
|
|
1586
|
-
"prepared input record exceeds page bound",
|
|
1587
|
-
));
|
|
1588
|
-
}
|
|
1589
|
-
break;
|
|
1590
|
-
}
|
|
1591
|
-
bytes += record_bytes;
|
|
1592
|
-
records.push(record);
|
|
1582
|
+
cursor
|
|
1583
|
+
.input_records
|
|
1584
|
+
.as_mut()
|
|
1585
|
+
.expect("input records")
|
|
1586
|
+
.extend(crate::snapshot_codec::predicate_input_records(&facts.inputs)?);
|
|
1593
1587
|
} else if facts.query(&cursor.query)?["value"].as_bool() == Some(true) {
|
|
1594
1588
|
let data = json!({"kind":"scalar","value":true});
|
|
1595
1589
|
encoded_size(&data, output_limit)?;
|
|
@@ -1599,7 +1593,9 @@ impl NativeStore {
|
|
|
1599
1593
|
steps += 1;
|
|
1600
1594
|
uncached_steps += usize::from(!cached);
|
|
1601
1595
|
}
|
|
1602
|
-
if cursor.next == total
|
|
1596
|
+
if cursor.next == total
|
|
1597
|
+
&& cursor.input_records.as_ref().is_none_or(VecDeque::is_empty)
|
|
1598
|
+
{
|
|
1603
1599
|
if !self.validate_source_stamps(
|
|
1604
1600
|
&sources,
|
|
1605
1601
|
context,
|
|
@@ -1781,8 +1777,10 @@ impl NativeStore {
|
|
|
1781
1777
|
encoded_size(&data, bounds.max_output_bytes)?;
|
|
1782
1778
|
return Ok((data, None, None));
|
|
1783
1779
|
}
|
|
1784
|
-
let
|
|
1785
|
-
Some(
|
|
1780
|
+
let input_records = if kind == "deep_predicate_inputs" {
|
|
1781
|
+
Some(VecDeque::from(crate::snapshot_codec::predicate_input_records(
|
|
1782
|
+
&root_facts.inputs,
|
|
1783
|
+
)?))
|
|
1786
1784
|
} else {
|
|
1787
1785
|
None
|
|
1788
1786
|
};
|
|
@@ -1791,7 +1789,7 @@ impl NativeStore {
|
|
|
1791
1789
|
graph_id: token.to_owned(),
|
|
1792
1790
|
query: query.clone(),
|
|
1793
1791
|
pending: None,
|
|
1794
|
-
|
|
1792
|
+
input_records,
|
|
1795
1793
|
next: 0,
|
|
1796
1794
|
page_output_bytes: bounds.max_output_bytes.min(MAX_DATA_BYTES),
|
|
1797
1795
|
remaining: bounds,
|
|
@@ -1456,6 +1456,31 @@ fn predicate_inputs_query(
|
|
|
1456
1456
|
next: usize,
|
|
1457
1457
|
work: &Work,
|
|
1458
1458
|
) -> Result<Projection, SnapshotError> {
|
|
1459
|
+
record_page(
|
|
1460
|
+
predicate_records(session)?.into_iter().map(Ok),
|
|
1461
|
+
"cc-transcript.predicate-inputs/1",
|
|
1462
|
+
next,
|
|
1463
|
+
false,
|
|
1464
|
+
work,
|
|
1465
|
+
)
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
pub fn predicate_input_records(
|
|
1469
|
+
snapshot: &TranscriptSnapshot,
|
|
1470
|
+
selectors: &Value,
|
|
1471
|
+
limits: &WorkLimits,
|
|
1472
|
+
cancel: &Cancellation,
|
|
1473
|
+
) -> Result<(Vec<String>, usize, usize), SnapshotError> {
|
|
1474
|
+
let request = json!({"view":{"attachments":[],"selectors":selectors}});
|
|
1475
|
+
let mut work = Work::new(snapshot, limits, cancel);
|
|
1476
|
+
let range = selected_range(&mut work, &request)?;
|
|
1477
|
+
work.charge_range(range.clone())?;
|
|
1478
|
+
let lift = lift_range(&mut work, &range, None)?;
|
|
1479
|
+
let records = predicate_records(&view(&lift, &range, snapshot))?;
|
|
1480
|
+
Ok((records, work.bytes, work.events))
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
fn predicate_records(session: &Session) -> Result<Vec<String>, SnapshotError> {
|
|
1459
1484
|
let calls = session.tool_calls().items();
|
|
1460
1485
|
let wire = PredicateInputWire {
|
|
1461
1486
|
calls: calls
|
|
@@ -1482,12 +1507,8 @@ fn predicate_inputs_query(
|
|
|
1482
1507
|
})
|
|
1483
1508
|
.collect(),
|
|
1484
1509
|
};
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
"cc-transcript.predicate-inputs/1",
|
|
1488
|
-
next,
|
|
1489
|
-
false,
|
|
1490
|
-
work,
|
|
1510
|
+
snapshot_codec::predicate_input_records(
|
|
1511
|
+
&sonic_rs::to_value(&wire).map_err(|error| invalid(error.to_string()))?,
|
|
1491
1512
|
)
|
|
1492
1513
|
}
|
|
1493
1514
|
|