cc-transcript 3.2.0__tar.gz → 3.3.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-3.2.0 → cc_transcript-3.3.0}/PKG-INFO +1 -1
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/__init__.py +8 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/models.py +33 -1
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/parser.py +5 -1
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/render.py +6 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/pyproject.toml +1 -1
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/rust/src/event.rs +11 -7
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/rust/src/model.rs +2 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/Cargo.lock +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/Cargo.toml +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/LICENSE +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/README.md +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/__main__.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/_parser_rs.pyi +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/activity.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/backend.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/builders.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/cli.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/context.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/corrections.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/decisions.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/discovery.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/disktruth.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/evidence.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/filterspec.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/ids.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/judge/__init__.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/judge/llm.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/judge/verdicts.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/messages.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/mining/__init__.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/mining/candidates.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/mining/confidence.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/mining/filterspec.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/mining/formats.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/mining/signals.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/mining/sourcekind.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/mining/store.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/py.typed +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/query.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/rust.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/sentiment/__init__.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/sentiment/buckets.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/sentiment/engine.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/sentiment/lexicon.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/sentiment/scorespec.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/store.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/cc_transcript/tools.py +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/rust/Cargo.toml +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/rust/data/afinn-en-165.tsv +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/rust/data/domain_overrides.tsv +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/rust/src/filter.rs +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/rust/src/lexicon.rs +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/rust/src/lib.rs +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/rust/src/score.rs +0 -0
- {cc_transcript-3.2.0 → cc_transcript-3.3.0}/rust/src/value.rs +0 -0
|
@@ -60,7 +60,9 @@ EXPORTS: dict[str, str] = {
|
|
|
60
60
|
"CcVersion",
|
|
61
61
|
"ContentBlock",
|
|
62
62
|
"EntryMeta",
|
|
63
|
+
"FallbackBlock",
|
|
63
64
|
"ModeEvent",
|
|
65
|
+
"OtherBlock",
|
|
64
66
|
"OtherEvent",
|
|
65
67
|
"SystemEvent",
|
|
66
68
|
"TextBlock",
|
|
@@ -426,9 +428,15 @@ if TYPE_CHECKING:
|
|
|
426
428
|
from cc_transcript.models import (
|
|
427
429
|
EntryMeta as EntryMeta,
|
|
428
430
|
)
|
|
431
|
+
from cc_transcript.models import (
|
|
432
|
+
FallbackBlock as FallbackBlock,
|
|
433
|
+
)
|
|
429
434
|
from cc_transcript.models import (
|
|
430
435
|
ModeEvent as ModeEvent,
|
|
431
436
|
)
|
|
437
|
+
from cc_transcript.models import (
|
|
438
|
+
OtherBlock as OtherBlock,
|
|
439
|
+
)
|
|
432
440
|
from cc_transcript.models import (
|
|
433
441
|
OtherEvent as OtherEvent,
|
|
434
442
|
)
|
|
@@ -83,7 +83,39 @@ class ToolResultBlock:
|
|
|
83
83
|
is_async: bool = False
|
|
84
84
|
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
@dataclass(frozen=True, slots=True)
|
|
87
|
+
class FallbackBlock:
|
|
88
|
+
"""A marker that the assistant turn fell back from one model to another.
|
|
89
|
+
|
|
90
|
+
Claude Code records this when a turn switches models mid-stream; it carries
|
|
91
|
+
no message content, only the two model names.
|
|
92
|
+
|
|
93
|
+
Attributes:
|
|
94
|
+
from_model: The model the turn started on.
|
|
95
|
+
to_model: The model the turn fell back to.
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
from_model: str
|
|
99
|
+
to_model: str
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@dataclass(frozen=True, slots=True)
|
|
103
|
+
class OtherBlock:
|
|
104
|
+
"""Any assistant content block whose ``type`` is not yet modeled.
|
|
105
|
+
|
|
106
|
+
The escape hatch that keeps an unrecognized block from crashing the parser
|
|
107
|
+
as Claude Code's transcript format evolves, mirroring :class:`OtherEvent`.
|
|
108
|
+
|
|
109
|
+
Attributes:
|
|
110
|
+
type: The block's ``type`` field.
|
|
111
|
+
raw: The block's full decoded payload.
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
type: str
|
|
115
|
+
raw: Mapping[str, Any]
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
ContentBlock = TextBlock | ThinkingBlock | ToolUseBlock | ToolResultBlock | FallbackBlock | OtherBlock
|
|
87
119
|
|
|
88
120
|
|
|
89
121
|
@dataclass(frozen=True, slots=True)
|
|
@@ -18,7 +18,9 @@ from cc_transcript.models import (
|
|
|
18
18
|
ContentBlock,
|
|
19
19
|
EntryMeta,
|
|
20
20
|
EventUuid,
|
|
21
|
+
FallbackBlock,
|
|
21
22
|
ModeEvent,
|
|
23
|
+
OtherBlock,
|
|
22
24
|
OtherEvent,
|
|
23
25
|
SessionId,
|
|
24
26
|
SystemEvent,
|
|
@@ -102,8 +104,10 @@ def parse_assistant_block(block: dict[str, Any]) -> ContentBlock:
|
|
|
102
104
|
return ThinkingBlock(block["thinking"])
|
|
103
105
|
case "tool_use":
|
|
104
106
|
return ToolUseBlock(id=ToolUseId(block["id"]), name=block["name"], input=block["input"])
|
|
107
|
+
case "fallback":
|
|
108
|
+
return FallbackBlock(from_model=block["from"]["model"], to_model=block["to"]["model"])
|
|
105
109
|
case unknown:
|
|
106
|
-
|
|
110
|
+
return OtherBlock(type=unknown, raw=block)
|
|
107
111
|
|
|
108
112
|
|
|
109
113
|
def parse_event(data: Mapping[str, Any]) -> TranscriptEvent | None:
|
|
@@ -13,7 +13,9 @@ import orjson
|
|
|
13
13
|
from cc_transcript.filterspec import event_kind, event_meta, event_text, tool_uses
|
|
14
14
|
from cc_transcript.models import (
|
|
15
15
|
AssistantEvent,
|
|
16
|
+
FallbackBlock,
|
|
16
17
|
ModeEvent,
|
|
18
|
+
OtherBlock,
|
|
17
19
|
OtherEvent,
|
|
18
20
|
SystemEvent,
|
|
19
21
|
TextBlock,
|
|
@@ -230,6 +232,10 @@ def block_payload(block: ContentBlock, *, width: int, thinking: bool) -> str:
|
|
|
230
232
|
)
|
|
231
233
|
case ToolResultBlock():
|
|
232
234
|
return ""
|
|
235
|
+
case FallbackBlock(from_model=src, to_model=dst):
|
|
236
|
+
return f"fallback {src}->{dst}"
|
|
237
|
+
case OtherBlock(type=type_):
|
|
238
|
+
return type_
|
|
233
239
|
|
|
234
240
|
|
|
235
241
|
def line_budget(width: int) -> Budget:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "cc-transcript"
|
|
3
|
-
version = "3.
|
|
3
|
+
version = "3.3.0"
|
|
4
4
|
description = "The Claude Code session-activity platform: a superset JSONL parser (Rust fast path, Python reference), typed tool calls with a cross-language content digest, turns/edits/evidence over one spine, context windows with labeled fidelity, unified decision and correction ledgers, LLM judging, and a transcript-investigation CLI."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "PolyForm-Noncommercial-1.0.0"
|
|
@@ -6,9 +6,9 @@ use pyo3::IntoPyObjectExt;
|
|
|
6
6
|
use sonic_rs::{JsonContainerTrait, JsonType, JsonValueTrait, Value};
|
|
7
7
|
|
|
8
8
|
use crate::model::{
|
|
9
|
-
models_type, ASSISTANT_EVENT_CLS, ENTRY_META_CLS,
|
|
10
|
-
SYSTEM_EVENT_CLS, TEXT_BLOCK_CLS, THINKING_BLOCK_CLS,
|
|
11
|
-
TOOL_USE_BLOCK_CLS, USER_EVENT_CLS,
|
|
9
|
+
models_type, ASSISTANT_EVENT_CLS, ENTRY_META_CLS, FALLBACK_BLOCK_CLS, MODE_EVENT_CLS,
|
|
10
|
+
OTHER_BLOCK_CLS, OTHER_EVENT_CLS, SYSTEM_EVENT_CLS, TEXT_BLOCK_CLS, THINKING_BLOCK_CLS,
|
|
11
|
+
TOOL_RESULT_BLOCK_CLS, TOOL_USE_BLOCK_CLS, USER_EVENT_CLS,
|
|
12
12
|
};
|
|
13
13
|
use crate::value::{block_type, field, field_bool, field_str};
|
|
14
14
|
|
|
@@ -148,10 +148,14 @@ fn parse_assistant_block<'py>(py: Python<'py>, block: &Value) -> PyResult<Bound<
|
|
|
148
148
|
require_str(block, "name")?,
|
|
149
149
|
json_to_py(py, require(block, "input")?)?,
|
|
150
150
|
)),
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
))
|
|
151
|
+
Some("fallback") => models_type(py, &FALLBACK_BLOCK_CLS, "FallbackBlock")?.call1((
|
|
152
|
+
require_str(require(block, "from")?, "model")?,
|
|
153
|
+
require_str(require(block, "to")?, "model")?,
|
|
154
|
+
)),
|
|
155
|
+
Some(other) => {
|
|
156
|
+
models_type(py, &OTHER_BLOCK_CLS, "OtherBlock")?.call1((other, json_to_py(py, block)?))
|
|
157
|
+
}
|
|
158
|
+
None => Err(PyKeyError::new_err("'type'")),
|
|
155
159
|
}
|
|
156
160
|
}
|
|
157
161
|
|
|
@@ -12,6 +12,8 @@ pub static TEXT_BLOCK_CLS: PyOnceLock<Py<PyType>> = PyOnceLock::new();
|
|
|
12
12
|
pub static THINKING_BLOCK_CLS: PyOnceLock<Py<PyType>> = PyOnceLock::new();
|
|
13
13
|
pub static TOOL_USE_BLOCK_CLS: PyOnceLock<Py<PyType>> = PyOnceLock::new();
|
|
14
14
|
pub static TOOL_RESULT_BLOCK_CLS: PyOnceLock<Py<PyType>> = PyOnceLock::new();
|
|
15
|
+
pub static FALLBACK_BLOCK_CLS: PyOnceLock<Py<PyType>> = PyOnceLock::new();
|
|
16
|
+
pub static OTHER_BLOCK_CLS: PyOnceLock<Py<PyType>> = PyOnceLock::new();
|
|
15
17
|
|
|
16
18
|
pub fn models_type<'py>(
|
|
17
19
|
py: Python<'py>,
|
|
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
|