cc-transcript 10.1.0__tar.gz → 10.2.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-10.1.0 → cc_transcript-10.2.0}/PKG-INFO +1 -1
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/activity.py +5 -3
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/activity_probe.py +1 -3
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/pyproject.toml +1 -1
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/rust/src/mining.rs +2 -8
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/rust/src/parse.rs +16 -3
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/Cargo.lock +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/Cargo.toml +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/LICENSE +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/README.md +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/__init__.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/__main__.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/_parser_rs.pyi +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/backend.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/builders.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/cli.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/command.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/context.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/corrections.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/corrections_cli.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/cost.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/decisions.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/discovery.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/disktruth.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/evidence.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/extract/__init__.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/extract/correct.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/facts.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/filterspec.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/ids.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/judge/__init__.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/judge/llm.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/judge/similar.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/judge/verdicts.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/mining/__init__.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/mining/candidates.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/mining/confidence.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/mining/engine.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/mining/filterspec.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/mining/formats.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/mining/signals.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/mining/sourcekind.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/mining/spec.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/mining/store.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/models.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/notifications.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/parser.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/py.typed +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/query.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/render.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/rust.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/sentiment/__init__.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/sentiment/buckets.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/sentiment/engine.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/sentiment/lexicon.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/sentiment/scorespec.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/store.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/cc_transcript/tools.py +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/rust/Cargo.toml +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/rust/build.rs +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/rust/data/afinn-en-165.tsv +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/rust/data/domain_overrides.tsv +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/rust/src/activity.rs +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/rust/src/command.rs +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/rust/src/event.rs +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/rust/src/filter.rs +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/rust/src/lexicon.rs +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/rust/src/lib.rs +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/rust/src/model.rs +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/rust/src/protocol.rs +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/rust/src/python.rs +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/rust/src/score.rs +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/rust/src/types.rs +0 -0
- {cc_transcript-10.1.0 → cc_transcript-10.2.0}/rust/src/value.rs +0 -0
|
@@ -39,10 +39,12 @@ UserClassifier = Callable[["UserEvent"], bool]
|
|
|
39
39
|
def native_user_classifier(event: UserEvent) -> bool:
|
|
40
40
|
"""Whether a user event is a real prompt under native Claude Code semantics.
|
|
41
41
|
|
|
42
|
-
A prompt is non-meta, non-sidechain, not
|
|
43
|
-
tool-result-only — it must carry real text.
|
|
42
|
+
A prompt is non-meta, non-sidechain, not a compact summary, not an
|
|
43
|
+
interruption marker, and not tool-result-only — it must carry real text.
|
|
44
44
|
"""
|
|
45
|
-
return not (
|
|
45
|
+
return not (
|
|
46
|
+
event.meta.is_meta or event.meta.is_sidechain or event.meta.is_compact_summary or event.interrupted
|
|
47
|
+
) and bool(event.text.strip())
|
|
46
48
|
|
|
47
49
|
|
|
48
50
|
@dataclass(frozen=True, slots=True)
|
|
@@ -129,9 +129,7 @@ def probe_events(
|
|
|
129
129
|
(
|
|
130
130
|
index
|
|
131
131
|
for index in reversed(range(len(events)))
|
|
132
|
-
if isinstance(event := events[index], UserEvent)
|
|
133
|
-
and native_user_classifier(event)
|
|
134
|
-
and not event.meta.is_compact_summary
|
|
132
|
+
if isinstance(event := events[index], UserEvent) and native_user_classifier(event)
|
|
135
133
|
),
|
|
136
134
|
0,
|
|
137
135
|
)
|
|
@@ -8,7 +8,7 @@ use regex::Regex;
|
|
|
8
8
|
use sonic_rs::{Index, JsonContainerTrait, JsonValueTrait, Value};
|
|
9
9
|
|
|
10
10
|
use crate::filter::compile_group_array;
|
|
11
|
-
use crate::parse::{
|
|
11
|
+
use crate::parse::{parse_bytes, ParseError};
|
|
12
12
|
use crate::protocol::{
|
|
13
13
|
embedded_user_text, interrupt_marker, is_bare_interrupt_marker, ANSWERED_PREFIX, ANSWERED_TRAILER,
|
|
14
14
|
DENIAL_PREFIX, INTERRUPT_MARKER_RE,
|
|
@@ -434,13 +434,7 @@ impl Events {
|
|
|
434
434
|
/// non-object values (parser.py decode_line) so event indices agree with the
|
|
435
435
|
/// Python reference; a malformed entry fails the mine, as in the reference.
|
|
436
436
|
fn parse(raw: &[u8]) -> Result<Self, ParseError> {
|
|
437
|
-
let entries = raw
|
|
438
|
-
.split(|&b| b == b'\n')
|
|
439
|
-
.filter(|line| !line.iter().all(u8::is_ascii_whitespace))
|
|
440
|
-
.filter_map(|line| sonic_rs::from_slice::<Value>(line).ok())
|
|
441
|
-
.filter(|value| value.is_object())
|
|
442
|
-
.map(parse_entry)
|
|
443
|
-
.collect::<Result<Vec<_>, _>>()?;
|
|
437
|
+
let entries = parse_bytes(raw, |_| true)?;
|
|
444
438
|
let texts = entries
|
|
445
439
|
.iter()
|
|
446
440
|
.map(|entry| match entry {
|
|
@@ -265,9 +265,10 @@ pub fn parse_entry(data: Value) -> Result<Entry, ParseError> {
|
|
|
265
265
|
Ok(Entry::Other(OtherEntry { ty, raw: data }))
|
|
266
266
|
}
|
|
267
267
|
|
|
268
|
-
//
|
|
269
|
-
//
|
|
270
|
-
//
|
|
268
|
+
// Non-JSON lines and valid-JSON lines that are not objects (bare scalars or
|
|
269
|
+
// arrays) are skipped; a JSON object that fails the typed parse (e.g. a missing
|
|
270
|
+
// required field) fails the whole file — whole-file parity with PythonBackend,
|
|
271
|
+
// which decodes every line, skips non-objects, then parses the rest.
|
|
271
272
|
fn parse_line<F: Fn(&Entry) -> bool>(
|
|
272
273
|
line: &[u8],
|
|
273
274
|
lines: &mut Vec<Entry>,
|
|
@@ -277,6 +278,9 @@ fn parse_line<F: Fn(&Entry) -> bool>(
|
|
|
277
278
|
return Ok(());
|
|
278
279
|
}
|
|
279
280
|
if let Ok(value) = sonic_rs::from_slice::<Value>(line) {
|
|
281
|
+
if !value.is_object() {
|
|
282
|
+
return Ok(());
|
|
283
|
+
}
|
|
280
284
|
let entry = parse_entry(value)?;
|
|
281
285
|
if keep(&entry) {
|
|
282
286
|
lines.push(entry);
|
|
@@ -614,6 +618,15 @@ mod tests {
|
|
|
614
618
|
assert_eq!(other.raw, parse(raw));
|
|
615
619
|
}
|
|
616
620
|
|
|
621
|
+
#[test]
|
|
622
|
+
fn parse_bytes_skips_valid_json_non_object_lines() {
|
|
623
|
+
let real = format!(r#"{{"type":"user",{META},"message":{{"content":"hi"}}}}"#);
|
|
624
|
+
let bytes = format!("{real}\n42\n\"bare\"\n[1,2,3]\n{real}");
|
|
625
|
+
let entries = parse_bytes(bytes.as_bytes(), |_| true).unwrap();
|
|
626
|
+
assert_eq!(entries.len(), 2, "bare scalar and array lines are skipped");
|
|
627
|
+
assert!(entries.iter().all(|e| matches!(e, Entry::User(_))));
|
|
628
|
+
}
|
|
629
|
+
|
|
617
630
|
#[test]
|
|
618
631
|
fn print_envelope_requires_result_element() {
|
|
619
632
|
assert!(matches!(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|