indent 0.1.14__tar.gz → 0.1.15__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.
Potentially problematic release.
This version of indent might be problematic. Click here for more details.
- {indent-0.1.14 → indent-0.1.15}/PKG-INFO +1 -1
- {indent-0.1.14 → indent-0.1.15}/exponent/__init__.py +2 -2
- {indent-0.1.14 → indent-0.1.15}/exponent/core/remote_execution/cli_rpc_types.py +3 -1
- {indent-0.1.14 → indent-0.1.15}/exponent/core/remote_execution/client.py +21 -17
- indent-0.1.15/exponent/core/remote_execution/tool_type_utils.py +39 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/remote_execution/types.py +4 -0
- {indent-0.1.14 → indent-0.1.15}/.gitignore +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/cli.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/commands/cloud_commands.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/commands/common.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/commands/config_commands.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/commands/run_commands.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/commands/settings.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/commands/types.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/commands/upgrade.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/commands/utils.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/commands/workflow_commands.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/config.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/graphql/__init__.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/graphql/client.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/graphql/get_chats_query.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/graphql/github_config_queries.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/graphql/mutations.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/graphql/queries.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/graphql/subscriptions.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/remote_execution/checkpoints.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/remote_execution/code_execution.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/remote_execution/error_info.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/remote_execution/exceptions.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/remote_execution/file_write.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/remote_execution/files.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/remote_execution/git.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/remote_execution/http_fetch.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/remote_execution/languages/python_execution.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/remote_execution/languages/shell_streaming.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/remote_execution/languages/types.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/remote_execution/session.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/remote_execution/system_context.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/remote_execution/tool_execution.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/remote_execution/truncation.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/remote_execution/utils.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/types/__init__.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/types/command_data.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/types/event_types.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/types/generated/__init__.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/core/types/generated/strategy_info.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/migration-docs/login.md +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/py.typed +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/utils/__init__.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/utils/colors.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/exponent/utils/version.py +0 -0
- {indent-0.1.14 → indent-0.1.15}/pyproject.toml +0 -0
|
@@ -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.15'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 1, 15)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -2,6 +2,7 @@ from typing import TYPE_CHECKING, Any
|
|
|
2
2
|
|
|
3
3
|
import msgspec
|
|
4
4
|
import yaml
|
|
5
|
+
from pydantic_ai.format_as_xml import format_as_xml
|
|
5
6
|
|
|
6
7
|
if TYPE_CHECKING:
|
|
7
8
|
from exponent_server.core.tools.edit_tool import (
|
|
@@ -28,6 +29,7 @@ class ToolInput(msgspec.Struct, tag_field="tool_name", omit_defaults=True):
|
|
|
28
29
|
return msgspec.to_builtins(self) # type: ignore[no-any-return]
|
|
29
30
|
|
|
30
31
|
def to_text(self) -> str:
|
|
32
|
+
"""This text is purely used for human debugging, it's not fed to the llm"""
|
|
31
33
|
d = msgspec.to_builtins(self)
|
|
32
34
|
del d["tool_name"]
|
|
33
35
|
return yaml.dump(d)
|
|
@@ -41,7 +43,7 @@ class ToolResult(msgspec.Struct, tag_field="tool_name", omit_defaults=True):
|
|
|
41
43
|
This provides a default textual representation of the tool result. Override it as needed for your tool."""
|
|
42
44
|
d = msgspec.to_builtins(self)
|
|
43
45
|
del d["tool_name"]
|
|
44
|
-
return
|
|
46
|
+
return format_as_xml(d, include_root_tag=False, item_tag="item")
|
|
45
47
|
|
|
46
48
|
|
|
47
49
|
class ErrorToolResult(ToolResult, tag="error"):
|
|
@@ -5,7 +5,7 @@ import json
|
|
|
5
5
|
import logging
|
|
6
6
|
import time
|
|
7
7
|
import uuid
|
|
8
|
-
from collections.abc import AsyncGenerator, Callable, Generator
|
|
8
|
+
from collections.abc import AsyncGenerator, Callable, Coroutine, Generator
|
|
9
9
|
from contextlib import asynccontextmanager
|
|
10
10
|
from dataclasses import dataclass
|
|
11
11
|
from typing import Any, TypeVar, cast
|
|
@@ -30,6 +30,7 @@ from exponent.core.remote_execution.cli_rpc_types import (
|
|
|
30
30
|
CliRpcRequest,
|
|
31
31
|
CliRpcResponse,
|
|
32
32
|
ErrorResponse,
|
|
33
|
+
ErrorToolResult,
|
|
33
34
|
GetAllFilesRequest,
|
|
34
35
|
GetAllFilesResponse,
|
|
35
36
|
HttpRequest,
|
|
@@ -611,33 +612,36 @@ class RemoteExecutionClient:
|
|
|
611
612
|
response=GetAllFilesResponse(files=files),
|
|
612
613
|
)
|
|
613
614
|
elif isinstance(request.request, BatchToolExecutionRequest):
|
|
614
|
-
|
|
615
|
+
coros: list[Coroutine[Any, Any, ToolResultType]] = []
|
|
615
616
|
for tool_input in request.request.tool_inputs:
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
617
|
+
if isinstance(tool_input, BashToolInput):
|
|
618
|
+
coros.append(
|
|
619
|
+
execute_bash_tool(
|
|
619
620
|
tool_input,
|
|
620
621
|
self.working_directory,
|
|
621
622
|
should_halt=self.get_halt_check(request.request_id),
|
|
622
623
|
)
|
|
623
|
-
else:
|
|
624
|
-
raw_result = await execute_tool( # type: ignore[assignment]
|
|
625
|
-
tool_input, self.working_directory
|
|
626
|
-
)
|
|
627
|
-
tool_result = truncate_result(raw_result)
|
|
628
|
-
results.append(tool_result)
|
|
629
|
-
except Exception as e:
|
|
630
|
-
logger.error(f"Error executing tool {tool_input}: {e}")
|
|
631
|
-
from exponent.core.remote_execution.cli_rpc_types import (
|
|
632
|
-
ErrorToolResult,
|
|
633
624
|
)
|
|
625
|
+
else:
|
|
626
|
+
coros.append(execute_tool(tool_input, self.working_directory))
|
|
627
|
+
|
|
628
|
+
results: list[ToolResultType | BaseException] = await asyncio.gather(
|
|
629
|
+
*coros, return_exceptions=True
|
|
630
|
+
)
|
|
634
631
|
|
|
635
|
-
|
|
632
|
+
processed_results: list[ToolResultType] = []
|
|
633
|
+
for result in results:
|
|
634
|
+
if not isinstance(result, BaseException):
|
|
635
|
+
processed_results.append(truncate_result(result))
|
|
636
|
+
else:
|
|
637
|
+
processed_results.append(
|
|
638
|
+
ErrorToolResult(error_message=str(result))
|
|
639
|
+
)
|
|
636
640
|
|
|
637
641
|
return CliRpcResponse(
|
|
638
642
|
request_id=request.request_id,
|
|
639
643
|
response=BatchToolExecutionResponse(
|
|
640
|
-
tool_results=
|
|
644
|
+
tool_results=processed_results,
|
|
641
645
|
),
|
|
642
646
|
)
|
|
643
647
|
elif isinstance(request.request, HttpRequest):
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import msgspec
|
|
4
|
+
|
|
5
|
+
from exponent.core.remote_execution.cli_rpc_types import ToolResult
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def to_mostly_xml(tool_result: ToolResult) -> str:
|
|
9
|
+
"""
|
|
10
|
+
This provides a default textual representation of the tool result. Override it as needed for your tool."""
|
|
11
|
+
d = msgspec.to_builtins(tool_result)
|
|
12
|
+
del d["tool_name"]
|
|
13
|
+
return to_mostly_xml_helper(d)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def to_mostly_xml_helper(
|
|
17
|
+
d: Any,
|
|
18
|
+
) -> str:
|
|
19
|
+
if isinstance(d, dict):
|
|
20
|
+
# No outer wrapper at top level, each field gets XML tags
|
|
21
|
+
parts = []
|
|
22
|
+
for key, value in d.items():
|
|
23
|
+
if isinstance(value, list):
|
|
24
|
+
# Handle lists with item tags
|
|
25
|
+
list_items = "\n".join(
|
|
26
|
+
f"<item>\n{to_mostly_xml_helper(item)}\n</item>" for item in value
|
|
27
|
+
)
|
|
28
|
+
parts.append(f"<{key}>\n{list_items}\n</{key}>")
|
|
29
|
+
elif isinstance(value, dict):
|
|
30
|
+
# Nested dict
|
|
31
|
+
parts.append(f"<{key}>\n{to_mostly_xml_helper(value)}\n</{key}>")
|
|
32
|
+
else:
|
|
33
|
+
# Scalar value
|
|
34
|
+
parts.append(f"<{key}>\n{value!s}\n</{key}>")
|
|
35
|
+
return "\n".join(parts)
|
|
36
|
+
elif isinstance(d, list):
|
|
37
|
+
raise ValueError("Lists are not allowed at the top level")
|
|
38
|
+
else:
|
|
39
|
+
return str(d)
|
|
@@ -517,6 +517,10 @@ class ChatMode(str, Enum):
|
|
|
517
517
|
DATABASE = "DATABASE" # chat with database connection
|
|
518
518
|
WORKFLOW = "WORKFLOW"
|
|
519
519
|
|
|
520
|
+
@classmethod
|
|
521
|
+
def requires_cli(cls, mode: "ChatMode") -> bool:
|
|
522
|
+
return mode not in [cls.DATABASE]
|
|
523
|
+
|
|
520
524
|
|
|
521
525
|
class ChatSource(str, Enum):
|
|
522
526
|
CLI_SHELL = "CLI_SHELL"
|
|
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
|
{indent-0.1.14 → indent-0.1.15}/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
|
|
File without changes
|