Repository navigation
Expand file tree
/
Copy pathmodels.py
More file actions
121 lines (95 loc) · 3.34 KB
/
Copy pathmodels.py
File metadata and controls
121 lines (95 loc) · 3.34 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
110
111
112
113
114
115
116
117
118
119
120
121
from collections.abc import Callable
from dataclasses import dataclass, field
from decimal import Decimal
from pathlib import Path
from typing import TYPE_CHECKING, NamedTuple
from rich.console import Console
from .constants import PermissionMode, SupportedLanguage
from .types_defs import MCPHandlerType, MCPInputSchema, PropertyValue
if TYPE_CHECKING:
from tree_sitter import Node
@dataclass
class SessionState:
confirm_edits: bool = True
load_cgr_instructions: bool = True
log_file: Path | None = None
cancelled: bool = False
permission_mode: PermissionMode = PermissionMode.NORMAL
context_tokens: int = 0
# Whether a rejected-API-key warning has already been emitted this
# session. The token counter refreshes on every turn, so without this the
# same unactionable-until-restart message repeats and buries the log
# (issue #1493).
token_auth_warned: bool = False
target_repo: Path | None = None
# Cumulative token consumption and USD cost across the session (issue #80).
total_input_tokens: int = 0
total_output_tokens: int = 0
total_cost_usd: Decimal = field(default_factory=lambda: Decimal(0))
# Set once any turn cannot be priced, so the session total is a floor.
cost_incomplete: bool = False
def reset_cancelled(self) -> None:
self.cancelled = False
def is_yolo(self) -> bool:
return self.permission_mode == PermissionMode.YOLO
def cycle_permission_mode(self) -> PermissionMode:
self.permission_mode = (
PermissionMode.YOLO
if self.permission_mode == PermissionMode.NORMAL
else PermissionMode.NORMAL
)
return self.permission_mode
def _default_console() -> Console:
return Console(width=None, force_terminal=True)
@dataclass
class AppContext:
session: SessionState = field(default_factory=SessionState)
console: Console = field(default_factory=_default_console)
@dataclass
class GraphNode:
node_id: int
labels: list[str]
properties: dict[str, PropertyValue]
@dataclass
class GraphRelationship:
from_id: int
to_id: int
type: str
properties: dict[str, PropertyValue]
class FQNSpec(NamedTuple):
scope_node_types: frozenset[str]
function_node_types: frozenset[str]
get_name: Callable[["Node"], str | None]
file_to_module_parts: Callable[[Path, Path], list[str]]
@dataclass(frozen=True)
class LanguageSpec:
language: SupportedLanguage | str
file_extensions: tuple[str, ...]
function_node_types: tuple[str, ...]
class_node_types: tuple[str, ...]
module_node_types: tuple[str, ...]
call_node_types: tuple[str, ...] = ()
import_node_types: tuple[str, ...] = ()
import_from_node_types: tuple[str, ...] = ()
name_field: str = "name"
body_field: str = "body"
package_indicators: tuple[str, ...] = ()
function_query: str | None = None
class_query: str | None = None
call_query: str | None = None
@dataclass
class Dependency:
name: str
spec: str
properties: dict[str, str] = field(default_factory=dict)
@dataclass
class MethodModifiersAndAnnotations:
modifiers: list[str] = field(default_factory=list)
annotations: list[str] = field(default_factory=list)
@dataclass
class ToolMetadata:
name: str
description: str
input_schema: MCPInputSchema
handler: MCPHandlerType
returns_json: bool