indent 0.1.21__tar.gz → 0.1.22__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.
- {indent-0.1.21 → indent-0.1.22}/PKG-INFO +2 -1
- {indent-0.1.21 → indent-0.1.22}/exponent/__init__.py +2 -2
- {indent-0.1.21 → indent-0.1.22}/exponent/commands/cloud_commands.py +2 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/graphql/mutations.py +2 -2
- indent-0.1.22/exponent/core/remote_execution/port_utils.py +73 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/system_context.py +2 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/types.py +9 -0
- {indent-0.1.21 → indent-0.1.22}/pyproject.toml +1 -0
- {indent-0.1.21 → indent-0.1.22}/.gitignore +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/cli.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/commands/common.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/commands/config_commands.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/commands/run_commands.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/commands/settings.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/commands/types.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/commands/upgrade.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/commands/utils.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/config.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/graphql/__init__.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/graphql/client.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/graphql/get_chats_query.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/graphql/queries.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/graphql/subscriptions.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/checkpoints.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/cli_rpc_types.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/client.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/code_execution.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/default_env.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/error_info.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/exceptions.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/file_write.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/files.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/git.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/http_fetch.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/languages/python_execution.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/languages/shell_streaming.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/languages/types.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/session.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/tool_execution.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/tool_type_utils.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/truncation.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/utils.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/types/__init__.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/types/command_data.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/types/event_types.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/types/generated/__init__.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/core/types/generated/strategy_info.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/migration-docs/login.md +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/py.typed +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/utils/__init__.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/utils/colors.py +0 -0
- {indent-0.1.21 → indent-0.1.22}/exponent/utils/version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: indent
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.22
|
|
4
4
|
Summary: Indent is an AI Pair Programmer
|
|
5
5
|
Author-email: Sashank Thupukari <sashank@exponent.run>
|
|
6
6
|
Requires-Python: <3.13,>=3.10
|
|
@@ -22,6 +22,7 @@ Requires-Dist: msgspec>=0.19.0
|
|
|
22
22
|
Requires-Dist: packaging~=24.1
|
|
23
23
|
Requires-Dist: pip<26,>=25.0.1
|
|
24
24
|
Requires-Dist: prompt-toolkit<4,>=3.0.36
|
|
25
|
+
Requires-Dist: psutil<7,>=5.9.0
|
|
25
26
|
Requires-Dist: pydantic-ai==0.0.30
|
|
26
27
|
Requires-Dist: pydantic-settings<3,>=2.2.1
|
|
27
28
|
Requires-Dist: pydantic[email]<3,>=2.6.4
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.1.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 1,
|
|
31
|
+
__version__ = version = '0.1.22'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 1, 22)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -111,6 +111,7 @@ async def create_cloud_chat_from_repository(
|
|
|
111
111
|
base_api_url: str,
|
|
112
112
|
base_ws_url: str,
|
|
113
113
|
repository_id: str,
|
|
114
|
+
provider: str | None = None,
|
|
114
115
|
) -> dict[str, Any]:
|
|
115
116
|
graphql_client = GraphQLClient(
|
|
116
117
|
api_key=api_key, base_api_url=base_api_url, base_ws_url=base_ws_url
|
|
@@ -118,6 +119,7 @@ async def create_cloud_chat_from_repository(
|
|
|
118
119
|
|
|
119
120
|
variables = {
|
|
120
121
|
"repositoryId": repository_id,
|
|
122
|
+
"provider": provider,
|
|
121
123
|
}
|
|
122
124
|
|
|
123
125
|
result = await graphql_client.execute(
|
|
@@ -76,8 +76,8 @@ mutation CreateCloudChat($configId: String!) {
|
|
|
76
76
|
|
|
77
77
|
|
|
78
78
|
CREATE_CLOUD_CHAT_FROM_REPOSITORY_MUTATION = """
|
|
79
|
-
mutation CreateCloudChatFromRepository($repositoryId: String
|
|
80
|
-
createCloudChat(repositoryId: $repositoryId) {
|
|
79
|
+
mutation CreateCloudChatFromRepository($repositoryId: String!, $provider: String) {
|
|
80
|
+
createCloudChat(repositoryId: $repositoryId, provider: $provider) {
|
|
81
81
|
__typename
|
|
82
82
|
...on Chat {
|
|
83
83
|
chatUuid
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import time
|
|
2
|
+
|
|
3
|
+
import psutil
|
|
4
|
+
|
|
5
|
+
from exponent.core.remote_execution.types import PortInfo
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_port_usage() -> list[PortInfo] | None:
|
|
9
|
+
"""
|
|
10
|
+
Get information about all listening ports on the system.
|
|
11
|
+
|
|
12
|
+
Returns:
|
|
13
|
+
List of PortInfo objects containing process name, port, protocol, pid, and uptime.
|
|
14
|
+
Returns None if there's a permission error.
|
|
15
|
+
Returns empty list if no listening ports are found.
|
|
16
|
+
"""
|
|
17
|
+
try:
|
|
18
|
+
connections = psutil.net_connections(kind="tcp")
|
|
19
|
+
except (psutil.AccessDenied, PermissionError):
|
|
20
|
+
# If we don't have permission to see connections, return None
|
|
21
|
+
return None
|
|
22
|
+
except Exception:
|
|
23
|
+
# For any other unexpected errors, return None
|
|
24
|
+
return None
|
|
25
|
+
|
|
26
|
+
port_info_list: list[PortInfo] = []
|
|
27
|
+
current_time = time.time()
|
|
28
|
+
|
|
29
|
+
for conn in connections:
|
|
30
|
+
# Only include TCP ports in LISTEN state
|
|
31
|
+
if conn.status != "LISTEN":
|
|
32
|
+
continue
|
|
33
|
+
|
|
34
|
+
# Skip if no local address (shouldn't happen for LISTEN, but be safe)
|
|
35
|
+
if not conn.laddr:
|
|
36
|
+
continue
|
|
37
|
+
|
|
38
|
+
port = conn.laddr.port
|
|
39
|
+
pid = conn.pid
|
|
40
|
+
|
|
41
|
+
# Try to get process information
|
|
42
|
+
process_name = "unknown"
|
|
43
|
+
uptime_seconds = None
|
|
44
|
+
|
|
45
|
+
if pid:
|
|
46
|
+
try:
|
|
47
|
+
process = psutil.Process(pid)
|
|
48
|
+
process_name = process.name()
|
|
49
|
+
|
|
50
|
+
# Calculate uptime
|
|
51
|
+
create_time = process.create_time()
|
|
52
|
+
uptime_seconds = current_time - create_time
|
|
53
|
+
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
|
54
|
+
# Process disappeared or we don't have permission
|
|
55
|
+
pass
|
|
56
|
+
except Exception:
|
|
57
|
+
# Any other unexpected error, just skip process info
|
|
58
|
+
pass
|
|
59
|
+
|
|
60
|
+
port_info = PortInfo(
|
|
61
|
+
process_name=process_name,
|
|
62
|
+
port=port,
|
|
63
|
+
protocol="TCP",
|
|
64
|
+
pid=pid,
|
|
65
|
+
uptime_seconds=uptime_seconds,
|
|
66
|
+
)
|
|
67
|
+
port_info_list.append(port_info)
|
|
68
|
+
|
|
69
|
+
# Limit to 50 ports to avoid bloating the heartbeat payload
|
|
70
|
+
if len(port_info_list) >= 50:
|
|
71
|
+
break
|
|
72
|
+
|
|
73
|
+
return port_info_list
|
|
@@ -4,6 +4,7 @@ import platform
|
|
|
4
4
|
|
|
5
5
|
from exponent.core.remote_execution.git import get_git_info
|
|
6
6
|
from exponent.core.remote_execution.languages import python_execution
|
|
7
|
+
from exponent.core.remote_execution.port_utils import get_port_usage
|
|
7
8
|
from exponent.core.remote_execution.types import (
|
|
8
9
|
SystemInfo,
|
|
9
10
|
)
|
|
@@ -17,6 +18,7 @@ async def get_system_info(working_directory: str) -> SystemInfo:
|
|
|
17
18
|
shell=_get_user_shell(),
|
|
18
19
|
git=await get_git_info(working_directory),
|
|
19
20
|
python_env=python_execution.get_python_env_info(),
|
|
21
|
+
port_usage=get_port_usage(),
|
|
20
22
|
)
|
|
21
23
|
|
|
22
24
|
|
|
@@ -120,6 +120,14 @@ class PythonEnvInfo(BaseModel):
|
|
|
120
120
|
provider: Literal["venv", "pyenv", "pipenv", "conda"] | None = "pyenv"
|
|
121
121
|
|
|
122
122
|
|
|
123
|
+
class PortInfo(BaseModel):
|
|
124
|
+
process_name: str
|
|
125
|
+
port: int
|
|
126
|
+
protocol: str
|
|
127
|
+
pid: int | None
|
|
128
|
+
uptime_seconds: float | None
|
|
129
|
+
|
|
130
|
+
|
|
123
131
|
class SystemInfo(BaseModel):
|
|
124
132
|
name: str
|
|
125
133
|
cwd: str
|
|
@@ -127,6 +135,7 @@ class SystemInfo(BaseModel):
|
|
|
127
135
|
shell: str
|
|
128
136
|
git: GitInfo | None
|
|
129
137
|
python_env: PythonEnvInfo | None
|
|
138
|
+
port_usage: list[PortInfo] | None = None
|
|
130
139
|
|
|
131
140
|
|
|
132
141
|
class HeartbeatInfo(BaseModel):
|
|
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
|
{indent-0.1.21 → indent-0.1.22}/exponent/core/remote_execution/languages/python_execution.py
RENAMED
|
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
|