forked from Alishahryar1/free-claude-code
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreasoning_details.py
More file actions
109 lines (90 loc) · 3.57 KB
/
Copy pathreasoning_details.py
File metadata and controls
109 lines (90 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
"""OpenRouter-format structured reasoning replay and stream conversion."""
import json
from collections.abc import Iterator, Mapping, Sequence
from typing import Any, Literal
from free_claude_code.core.inference import (
InferenceEvent,
InferenceStreamLedger,
ReplayArtifact,
ReplayArtifactKind,
ReplayArtifactOrigin,
ReplayAttachment,
ReplayCompatibilityScope,
)
class StructuredReasoningStream:
"""Reconcile alternate plaintext reasoning representations for one stream."""
def __init__(self, replay_scope: ReplayCompatibilityScope) -> None:
self._text_source: Literal["native", "details"] | None = None
self._replay_scope = replay_scope
def events(
self,
delta: Any,
ledger: InferenceStreamLedger,
*,
native_reasoning: str | None,
) -> Iterator[InferenceEvent]:
"""Emit plaintext once while preserving every opaque reasoning detail."""
details = _reasoning_details(delta)
if self._text_source is None:
if native_reasoning:
self._text_source = "native"
elif any(_reasoning_detail_text(detail) for detail in details):
self._text_source = "details"
if self._text_source == "native" and native_reasoning:
yield from ledger.ensure_reasoning_block()
yield ledger.emit_reasoning_delta(native_reasoning)
for detail in details:
if self._text_source == "details":
text = _reasoning_detail_text(detail)
if text:
yield from ledger.ensure_reasoning_block()
yield ledger.emit_reasoning_delta(text)
preserved = _preserved_reasoning_detail(detail)
if preserved:
yield from ledger.emit_reasoning_artifact(
ReplayArtifact(
origin=ReplayArtifactOrigin.OPENROUTER,
kind=ReplayArtifactKind.REASONING_DETAILS,
attachment=ReplayAttachment.REASONING,
payload=preserved,
scope=self._replay_scope,
)
)
def _reasoning_details(delta: Any) -> Sequence[Any]:
details = _field(delta, "reasoning_details")
if details is None:
extra = _field(delta, "model_extra")
if isinstance(extra, Mapping):
details = extra.get("reasoning_details")
return details if _is_sequence(details) else ()
def _reasoning_detail_text(detail: Any) -> str | None:
kind = str(_field(detail, "type") or "").lower()
if "encrypted" in kind or "redacted" in kind:
return None
for key in ("text", "content", "reasoning"):
value = _field(detail, key)
if isinstance(value, str) and value:
return value
return None
def _preserved_reasoning_detail(detail: Any) -> str | None:
if not isinstance(detail, Mapping):
return None
kind = str(_field(detail, "type") or "").lower()
signature = _field(detail, "signature")
if (
"encrypted" in kind
or "redacted" in kind
or "summary" in kind
or isinstance(signature, str)
or _reasoning_detail_text(detail) is None
):
return json.dumps(dict(detail), separators=(",", ":"))
return None
def _field(item: Any, name: str) -> Any:
if isinstance(item, Mapping):
return item.get(name)
return getattr(item, name, None)
def _is_sequence(value: Any) -> bool:
return isinstance(value, Sequence) and not isinstance(
value, str | bytes | bytearray
)