scalebox-sdk 0.1.0__py3-none-any.whl
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.
- scalebox/__init__.py +80 -0
- scalebox/api/__init__.py +128 -0
- scalebox/api/client/__init__.py +8 -0
- scalebox/api/client/api/__init__.py +1 -0
- scalebox/api/client/api/sandboxes/__init__.py +0 -0
- scalebox/api/client/api/sandboxes/delete_sandboxes_sandbox_id.py +161 -0
- scalebox/api/client/api/sandboxes/get_sandboxes.py +176 -0
- scalebox/api/client/api/sandboxes/get_sandboxes_metrics.py +173 -0
- scalebox/api/client/api/sandboxes/get_sandboxes_sandbox_id.py +163 -0
- scalebox/api/client/api/sandboxes/get_sandboxes_sandbox_id_logs.py +199 -0
- scalebox/api/client/api/sandboxes/get_sandboxes_sandbox_id_metrics.py +214 -0
- scalebox/api/client/api/sandboxes/get_v2_sandboxes.py +229 -0
- scalebox/api/client/api/sandboxes/post_sandboxes.py +174 -0
- scalebox/api/client/api/sandboxes/post_sandboxes_sandbox_id_pause.py +165 -0
- scalebox/api/client/api/sandboxes/post_sandboxes_sandbox_id_refreshes.py +182 -0
- scalebox/api/client/api/sandboxes/post_sandboxes_sandbox_id_resume.py +190 -0
- scalebox/api/client/api/sandboxes/post_sandboxes_sandbox_id_timeout.py +194 -0
- scalebox/api/client/client.py +288 -0
- scalebox/api/client/errors.py +16 -0
- scalebox/api/client/models/__init__.py +81 -0
- scalebox/api/client/models/build_log_entry.py +79 -0
- scalebox/api/client/models/created_access_token.py +100 -0
- scalebox/api/client/models/created_team_api_key.py +166 -0
- scalebox/api/client/models/error.py +67 -0
- scalebox/api/client/models/identifier_masking_details.py +83 -0
- scalebox/api/client/models/listed_sandbox.py +138 -0
- scalebox/api/client/models/log_level.py +11 -0
- scalebox/api/client/models/new_access_token.py +59 -0
- scalebox/api/client/models/new_sandbox.py +125 -0
- scalebox/api/client/models/new_team_api_key.py +59 -0
- scalebox/api/client/models/node.py +154 -0
- scalebox/api/client/models/node_detail.py +152 -0
- scalebox/api/client/models/node_status.py +11 -0
- scalebox/api/client/models/node_status_change.py +61 -0
- scalebox/api/client/models/post_sandboxes_sandbox_id_refreshes_body.py +59 -0
- scalebox/api/client/models/post_sandboxes_sandbox_id_timeout_body.py +59 -0
- scalebox/api/client/models/resumed_sandbox.py +68 -0
- scalebox/api/client/models/sandbox.py +125 -0
- scalebox/api/client/models/sandbox_detail.py +178 -0
- scalebox/api/client/models/sandbox_log.py +70 -0
- scalebox/api/client/models/sandbox_logs.py +73 -0
- scalebox/api/client/models/sandbox_metric.py +110 -0
- scalebox/api/client/models/sandbox_state.py +9 -0
- scalebox/api/client/models/sandboxes_with_metrics.py +59 -0
- scalebox/api/client/models/team.py +83 -0
- scalebox/api/client/models/team_api_key.py +158 -0
- scalebox/api/client/models/team_user.py +68 -0
- scalebox/api/client/models/template.py +179 -0
- scalebox/api/client/models/template_build.py +117 -0
- scalebox/api/client/models/template_build_file_upload.py +70 -0
- scalebox/api/client/models/template_build_request.py +115 -0
- scalebox/api/client/models/template_build_request_v2.py +88 -0
- scalebox/api/client/models/template_build_start_v2.py +114 -0
- scalebox/api/client/models/template_build_status.py +11 -0
- scalebox/api/client/models/template_step.py +91 -0
- scalebox/api/client/models/template_update_request.py +59 -0
- scalebox/api/client/models/update_team_api_key.py +59 -0
- scalebox/api/client/py.typed +1 -0
- scalebox/api/client/types.py +46 -0
- scalebox/api/metadata.py +19 -0
- scalebox/cli.py +125 -0
- scalebox/client/__init__.py +0 -0
- scalebox/client/aclient.py +57 -0
- scalebox/client/api.proto +460 -0
- scalebox/client/buf.gen.yaml +8 -0
- scalebox/client/client.py +102 -0
- scalebox/client/requirements.txt +5 -0
- scalebox/code_interpreter/__init__.py +12 -0
- scalebox/code_interpreter/charts.py +230 -0
- scalebox/code_interpreter/code_interpreter_async.py +369 -0
- scalebox/code_interpreter/code_interpreter_sync.py +317 -0
- scalebox/code_interpreter/constants.py +3 -0
- scalebox/code_interpreter/exceptions.py +13 -0
- scalebox/code_interpreter/models.py +485 -0
- scalebox/connection_config.py +92 -0
- scalebox/csx_connect/__init__.py +1 -0
- scalebox/csx_connect/client.py +485 -0
- scalebox/csx_desktop/__init__.py +0 -0
- scalebox/csx_desktop/main.py +651 -0
- scalebox/exceptions.py +83 -0
- scalebox/generated/__init__.py +0 -0
- scalebox/generated/api.py +61 -0
- scalebox/generated/api_pb2.py +203 -0
- scalebox/generated/api_pb2.pyi +956 -0
- scalebox/generated/api_pb2_connect.py +1456 -0
- scalebox/generated/rpc.py +50 -0
- scalebox/generated/versions.py +3 -0
- scalebox/requirements.txt +36 -0
- scalebox/sandbox/__init__.py +0 -0
- scalebox/sandbox/commands/__init__.py +0 -0
- scalebox/sandbox/commands/command_handle.py +69 -0
- scalebox/sandbox/commands/main.py +39 -0
- scalebox/sandbox/filesystem/__init__.py +0 -0
- scalebox/sandbox/filesystem/filesystem.py +95 -0
- scalebox/sandbox/filesystem/watch_handle.py +60 -0
- scalebox/sandbox/main.py +139 -0
- scalebox/sandbox/sandbox_api.py +91 -0
- scalebox/sandbox/signature.py +40 -0
- scalebox/sandbox/utils.py +34 -0
- scalebox/sandbox_async/__init__.py +1 -0
- scalebox/sandbox_async/commands/command.py +307 -0
- scalebox/sandbox_async/commands/command_handle.py +187 -0
- scalebox/sandbox_async/commands/pty.py +187 -0
- scalebox/sandbox_async/filesystem/filesystem.py +557 -0
- scalebox/sandbox_async/filesystem/watch_handle.py +61 -0
- scalebox/sandbox_async/main.py +646 -0
- scalebox/sandbox_async/sandbox_api.py +365 -0
- scalebox/sandbox_async/utils.py +7 -0
- scalebox/sandbox_sync/__init__.py +2 -0
- scalebox/sandbox_sync/commands/__init__.py +0 -0
- scalebox/sandbox_sync/commands/command.py +300 -0
- scalebox/sandbox_sync/commands/command_handle.py +150 -0
- scalebox/sandbox_sync/commands/pty.py +181 -0
- scalebox/sandbox_sync/filesystem/__init__.py +0 -0
- scalebox/sandbox_sync/filesystem/filesystem.py +543 -0
- scalebox/sandbox_sync/filesystem/watch_handle.py +66 -0
- scalebox/sandbox_sync/main.py +790 -0
- scalebox/sandbox_sync/sandbox_api.py +356 -0
- scalebox/test/CODE_INTERPRETER_TESTS_READY.md +323 -0
- scalebox/test/README.md +329 -0
- scalebox/test/__init__.py +0 -0
- scalebox/test/aclient.py +72 -0
- scalebox/test/code_interpreter_centext.py +21 -0
- scalebox/test/code_interpreter_centext_sync.py +21 -0
- scalebox/test/code_interpreter_test.py +34 -0
- scalebox/test/code_interpreter_test_sync.py +34 -0
- scalebox/test/run_all_validation_tests.py +334 -0
- scalebox/test/run_code_interpreter_tests.sh +67 -0
- scalebox/test/run_tests.sh +230 -0
- scalebox/test/test_basic.py +78 -0
- scalebox/test/test_code_interpreter_async_comprehensive.py +2653 -0
- scalebox/test/test_code_interpreter_e2basync_comprehensive.py +2655 -0
- scalebox/test/test_code_interpreter_e2bsync_comprehensive.py +3416 -0
- scalebox/test/test_code_interpreter_sync_comprehensive.py +3412 -0
- scalebox/test/test_e2b_first.py +11 -0
- scalebox/test/test_sandbox_async_comprehensive.py +738 -0
- scalebox/test/test_sandbox_stress_and_edge_cases.py +778 -0
- scalebox/test/test_sandbox_sync_comprehensive.py +770 -0
- scalebox/test/test_sandbox_usage_examples.py +987 -0
- scalebox/test/testacreate.py +24 -0
- scalebox/test/testagetinfo.py +18 -0
- scalebox/test/testcodeinterpreter_async.py +508 -0
- scalebox/test/testcodeinterpreter_sync.py +239 -0
- scalebox/test/testcomputeuse.py +243 -0
- scalebox/test/testnovnc.py +12 -0
- scalebox/test/testsandbox_async.py +118 -0
- scalebox/test/testsandbox_sync.py +38 -0
- scalebox/utils/__init__.py +0 -0
- scalebox/utils/httpcoreclient.py +297 -0
- scalebox/utils/httpxclient.py +403 -0
- scalebox/version.py +16 -0
- scalebox_sdk-0.1.0.dist-info/METADATA +292 -0
- scalebox_sdk-0.1.0.dist-info/RECORD +157 -0
- scalebox_sdk-0.1.0.dist-info/WHEEL +5 -0
- scalebox_sdk-0.1.0.dist-info/entry_points.txt +2 -0
- scalebox_sdk-0.1.0.dist-info/licenses/LICENSE +21 -0
- scalebox_sdk-0.1.0.dist-info/top_level.txt +1 -0
scalebox/cli.py
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Command-line interface for ScaleBox Python SDK
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import asyncio
|
|
7
|
+
import sys
|
|
8
|
+
from typing import Optional
|
|
9
|
+
|
|
10
|
+
from . import __version__
|
|
11
|
+
from .code_interpreter import AsyncSandbox, Sandbox
|
|
12
|
+
from .connection_config import ConnectionConfig
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def create_parser() -> argparse.ArgumentParser:
|
|
16
|
+
"""Create the command-line argument parser."""
|
|
17
|
+
parser = argparse.ArgumentParser(
|
|
18
|
+
prog="scalebox",
|
|
19
|
+
description="ScaleBox Python SDK - Multi-language code execution sandbox",
|
|
20
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
parser.add_argument(
|
|
24
|
+
"--version",
|
|
25
|
+
action="version",
|
|
26
|
+
version=f"ScaleBox Python SDK {__version__}",
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
subparsers = parser.add_subparsers(dest="command", help="Available commands")
|
|
30
|
+
|
|
31
|
+
# Sandbox command
|
|
32
|
+
sandbox_parser = subparsers.add_parser("sandbox", help="Sandbox operations")
|
|
33
|
+
sandbox_parser.add_argument(
|
|
34
|
+
"--create", action="store_true", help="Create a new sandbox"
|
|
35
|
+
)
|
|
36
|
+
sandbox_parser.add_argument("--list", action="store_true", help="List sandboxes")
|
|
37
|
+
sandbox_parser.add_argument("--destroy", help="Destroy a sandbox by ID")
|
|
38
|
+
|
|
39
|
+
# Code execution command
|
|
40
|
+
exec_parser = subparsers.add_parser("exec", help="Execute code")
|
|
41
|
+
exec_parser.add_argument("--code", required=True, help="Code to execute")
|
|
42
|
+
exec_parser.add_argument(
|
|
43
|
+
"--language", default="python", help="Programming language"
|
|
44
|
+
)
|
|
45
|
+
exec_parser.add_argument("--sandbox-id", help="Sandbox ID to use")
|
|
46
|
+
exec_parser.add_argument(
|
|
47
|
+
"--async-mode", action="store_true", help="Use async execution"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
# Configuration
|
|
51
|
+
parser.add_argument("--api-key", help="API key for authentication")
|
|
52
|
+
parser.add_argument("--domain", help="API domain")
|
|
53
|
+
parser.add_argument("--debug", action="store_true", help="Enable debug mode")
|
|
54
|
+
|
|
55
|
+
return parser
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
async def async_main():
|
|
59
|
+
"""Async main function."""
|
|
60
|
+
parser = create_parser()
|
|
61
|
+
args = parser.parse_args()
|
|
62
|
+
|
|
63
|
+
if not args.command:
|
|
64
|
+
parser.print_help()
|
|
65
|
+
return
|
|
66
|
+
|
|
67
|
+
# Create connection config
|
|
68
|
+
config = ConnectionConfig(
|
|
69
|
+
api_key=args.api_key,
|
|
70
|
+
domain=args.domain,
|
|
71
|
+
debug=args.debug,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
if args.command == "sandbox":
|
|
75
|
+
if args.create:
|
|
76
|
+
print("Creating sandbox...")
|
|
77
|
+
if args.async_mode:
|
|
78
|
+
sandbox = await AsyncSandbox.create()
|
|
79
|
+
print(f"Created async sandbox: {sandbox.id}")
|
|
80
|
+
else:
|
|
81
|
+
sandbox = Sandbox.create()
|
|
82
|
+
print(f"Created sandbox: {sandbox.id}")
|
|
83
|
+
elif args.list:
|
|
84
|
+
print("Listing sandboxes...")
|
|
85
|
+
# TODO: Implement sandbox listing
|
|
86
|
+
print("Sandbox listing not implemented yet")
|
|
87
|
+
elif args.destroy:
|
|
88
|
+
print(f"Destroying sandbox: {args.destroy}")
|
|
89
|
+
# TODO: Implement sandbox destruction
|
|
90
|
+
print("Sandbox destruction not implemented yet")
|
|
91
|
+
|
|
92
|
+
elif args.command == "exec":
|
|
93
|
+
print(f"Executing {args.language} code...")
|
|
94
|
+
print(f"Code: {args.code}")
|
|
95
|
+
|
|
96
|
+
if args.async_mode:
|
|
97
|
+
sandbox = await AsyncSandbox.create()
|
|
98
|
+
try:
|
|
99
|
+
result = await sandbox.run_code(args.code, language=args.language)
|
|
100
|
+
print(f"Result: {result.logs.stdout}")
|
|
101
|
+
finally:
|
|
102
|
+
await sandbox.close()
|
|
103
|
+
else:
|
|
104
|
+
sandbox = Sandbox.create()
|
|
105
|
+
try:
|
|
106
|
+
result = sandbox.run_code(args.code, language=args.language)
|
|
107
|
+
print(f"Result: {result.logs.stdout}")
|
|
108
|
+
finally:
|
|
109
|
+
sandbox.close()
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def main():
|
|
113
|
+
"""Main entry point."""
|
|
114
|
+
try:
|
|
115
|
+
asyncio.run(async_main())
|
|
116
|
+
except KeyboardInterrupt:
|
|
117
|
+
print("\nOperation cancelled by user")
|
|
118
|
+
sys.exit(1)
|
|
119
|
+
except Exception as e:
|
|
120
|
+
print(f"Error: {e}")
|
|
121
|
+
sys.exit(1)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
if __name__ == "__main__":
|
|
125
|
+
main()
|
|
File without changes
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# import sys, os
|
|
2
|
+
# sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../../scalebox'))
|
|
3
|
+
import asyncio
|
|
4
|
+
|
|
5
|
+
import aiohttp
|
|
6
|
+
from generated import api_pb2
|
|
7
|
+
from generated.api_pb2_connect import AsyncFilesystemClient
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
async def watch_directory_example():
|
|
11
|
+
# 创建 aiohttp 客户端会话
|
|
12
|
+
async with aiohttp.ClientSession() as session:
|
|
13
|
+
# 创建文件系统客户端
|
|
14
|
+
client = AsyncFilesystemClient(
|
|
15
|
+
base_url="http://localhost:8080",
|
|
16
|
+
http_client=session,
|
|
17
|
+
# protocol=ConnectProtocol.CONNECT_PROTOBUF # 如果需要指定协议
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
# 创建监视请求
|
|
21
|
+
request = api_pb2.WatchDirRequest(path="/root")
|
|
22
|
+
|
|
23
|
+
# 可选:添加额外的请求头
|
|
24
|
+
extra_headers = {
|
|
25
|
+
"Authorization": "Bearer root",
|
|
26
|
+
"X-Custom-Header": "custom-value",
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
# 使用 async for 循环处理流式响应
|
|
31
|
+
async for response in client.watch_dir(
|
|
32
|
+
request, extra_headers=extra_headers
|
|
33
|
+
):
|
|
34
|
+
print(f"Received event: {response}")
|
|
35
|
+
# 在这里处理每个事件
|
|
36
|
+
# 例如,根据事件类型执行不同的操作
|
|
37
|
+
|
|
38
|
+
# 如果收到特定事件,可以中断循环
|
|
39
|
+
# if response.event_type == api_pb2.WatchDirResponse.EVENT_TYPE_STOP:
|
|
40
|
+
# break
|
|
41
|
+
|
|
42
|
+
except Exception as e:
|
|
43
|
+
print(f"Error during directory watching: {e}")
|
|
44
|
+
|
|
45
|
+
finally:
|
|
46
|
+
# 关闭会话(在 with 语句中会自动关闭,但这里为了清晰展示)
|
|
47
|
+
await session.close()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
async def main():
|
|
51
|
+
# 运行监视示例
|
|
52
|
+
await watch_directory_example()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
if __name__ == "__main__":
|
|
56
|
+
# 运行异步主函数
|
|
57
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
package sandboxagent;
|
|
3
|
+
import "google/protobuf/timestamp.proto";
|
|
4
|
+
option go_package = "./pb";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
service Filesystem {
|
|
8
|
+
rpc Stat(StatRequest) returns (StatResponse);
|
|
9
|
+
rpc MakeDir(MakeDirRequest) returns (MakeDirResponse);
|
|
10
|
+
rpc Move(MoveRequest) returns (MoveResponse);
|
|
11
|
+
rpc ListDir(ListDirRequest) returns (ListDirResponse);
|
|
12
|
+
rpc Remove(RemoveRequest) returns (RemoveResponse);
|
|
13
|
+
|
|
14
|
+
rpc WatchDir(WatchDirRequest) returns (stream WatchDirResponse);
|
|
15
|
+
|
|
16
|
+
// Non-streaming versions of WatchDir
|
|
17
|
+
rpc CreateWatcher(CreateWatcherRequest) returns (CreateWatcherResponse);
|
|
18
|
+
rpc GetWatcherEvents(GetWatcherEventsRequest) returns (GetWatcherEventsResponse);
|
|
19
|
+
rpc RemoveWatcher(RemoveWatcherRequest) returns (RemoveWatcherResponse);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
message MoveRequest {
|
|
23
|
+
string source = 1;
|
|
24
|
+
string destination = 2;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
message MoveResponse {
|
|
28
|
+
EntryInfo entry = 1;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
message MakeDirRequest {
|
|
32
|
+
string path = 1;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
message MakeDirResponse {
|
|
36
|
+
EntryInfo entry = 1;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
message RemoveRequest {
|
|
40
|
+
string path = 1;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
message RemoveResponse {}
|
|
44
|
+
|
|
45
|
+
message StatRequest {
|
|
46
|
+
string path = 1;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
message StatResponse {
|
|
50
|
+
EntryInfo entry = 1;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
message EntryInfo {
|
|
54
|
+
string name = 1;
|
|
55
|
+
FileType type = 2;
|
|
56
|
+
string path = 3;
|
|
57
|
+
int64 size = 4;
|
|
58
|
+
uint32 mode = 5;
|
|
59
|
+
string permissions = 6;
|
|
60
|
+
string owner = 7;
|
|
61
|
+
string group = 8;
|
|
62
|
+
google.protobuf.Timestamp modified_time = 9;
|
|
63
|
+
// If the entry is a symlink, this field contains the target of the symlink.
|
|
64
|
+
optional string symlink_target = 10;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
enum FileType {
|
|
68
|
+
FILE_TYPE_UNSPECIFIED = 0;
|
|
69
|
+
FILE_TYPE_FILE = 1;
|
|
70
|
+
FILE_TYPE_DIRECTORY = 2;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
message ListDirRequest {
|
|
74
|
+
string path = 1;
|
|
75
|
+
uint32 depth = 2;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
message ListDirResponse {
|
|
79
|
+
repeated EntryInfo entries = 1;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
message WatchDirRequest {
|
|
83
|
+
string path = 1;
|
|
84
|
+
bool recursive = 2;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
message FilesystemEvent {
|
|
88
|
+
string name = 1;
|
|
89
|
+
EventType type = 2;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
message WatchDirResponse {
|
|
93
|
+
oneof event {
|
|
94
|
+
StartEvent start = 1;
|
|
95
|
+
FilesystemEvent filesystem = 2;
|
|
96
|
+
KeepAlive keepalive = 3;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
message StartEvent {}
|
|
100
|
+
|
|
101
|
+
message KeepAlive {}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
message CreateWatcherRequest {
|
|
105
|
+
string path = 1;
|
|
106
|
+
bool recursive = 2;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
message CreateWatcherResponse {
|
|
110
|
+
string watcher_id = 1;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
message GetWatcherEventsRequest {
|
|
114
|
+
string watcher_id = 1;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
message GetWatcherEventsResponse {
|
|
118
|
+
repeated FilesystemEvent events = 1;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
message RemoveWatcherRequest {
|
|
122
|
+
string watcher_id = 1;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
message RemoveWatcherResponse {}
|
|
126
|
+
|
|
127
|
+
enum EventType {
|
|
128
|
+
EVENT_TYPE_UNSPECIFIED = 0;
|
|
129
|
+
EVENT_TYPE_CREATE = 1;
|
|
130
|
+
EVENT_TYPE_WRITE = 2;
|
|
131
|
+
EVENT_TYPE_REMOVE = 3;
|
|
132
|
+
EVENT_TYPE_RENAME = 4;
|
|
133
|
+
EVENT_TYPE_CHMOD = 5;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
service Process {
|
|
138
|
+
rpc List(ListRequest) returns (ListResponse);
|
|
139
|
+
|
|
140
|
+
rpc Connect(ConnectRequest) returns (stream ConnectResponse);
|
|
141
|
+
rpc Start(StartRequest) returns (stream StartResponse);
|
|
142
|
+
|
|
143
|
+
rpc Update(UpdateRequest) returns (UpdateResponse);
|
|
144
|
+
|
|
145
|
+
// Client input stream ensures ordering of messages
|
|
146
|
+
rpc StreamInput(stream StreamInputRequest) returns (StreamInputResponse);
|
|
147
|
+
rpc SendInput(SendInputRequest) returns (SendInputResponse);
|
|
148
|
+
rpc SendSignal(SendSignalRequest) returns (SendSignalResponse);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
message PTY {
|
|
152
|
+
Size size = 1;
|
|
153
|
+
|
|
154
|
+
message Size {
|
|
155
|
+
uint32 cols = 1;
|
|
156
|
+
uint32 rows = 2;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
message ProcessConfig {
|
|
161
|
+
string cmd = 1;
|
|
162
|
+
repeated string args = 2;
|
|
163
|
+
|
|
164
|
+
map<string, string> envs = 3;
|
|
165
|
+
optional string cwd = 4;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
message ListRequest {}
|
|
169
|
+
|
|
170
|
+
message ProcessInfo {
|
|
171
|
+
ProcessConfig config = 1;
|
|
172
|
+
uint32 pid = 2;
|
|
173
|
+
optional string tag = 3;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
message ListResponse {
|
|
177
|
+
repeated ProcessInfo processes = 1;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
message StartRequest {
|
|
181
|
+
ProcessConfig process = 1;
|
|
182
|
+
optional PTY pty = 2;
|
|
183
|
+
optional string tag = 3;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
message UpdateRequest {
|
|
187
|
+
ProcessSelector process = 1;
|
|
188
|
+
|
|
189
|
+
optional PTY pty = 2;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
message UpdateResponse {}
|
|
193
|
+
|
|
194
|
+
message ProcessEvent {
|
|
195
|
+
oneof event {
|
|
196
|
+
StartEvent start = 1;
|
|
197
|
+
DataEvent data = 2;
|
|
198
|
+
EndEvent end = 3;
|
|
199
|
+
KeepAlive keepalive = 4;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
message StartEvent {
|
|
203
|
+
uint32 pid = 1;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
message DataEvent {
|
|
207
|
+
oneof output {
|
|
208
|
+
bytes stdout = 1;
|
|
209
|
+
bytes stderr = 2;
|
|
210
|
+
bytes pty = 3;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
message EndEvent {
|
|
215
|
+
sint32 exit_code = 1;
|
|
216
|
+
bool exited = 2;
|
|
217
|
+
string status = 3;
|
|
218
|
+
optional string error = 4;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
message KeepAlive {}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
message StartResponse {
|
|
225
|
+
ProcessEvent event = 1;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
message ConnectResponse {
|
|
229
|
+
ProcessEvent event = 1;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
message SendInputRequest {
|
|
233
|
+
ProcessSelector process = 1;
|
|
234
|
+
|
|
235
|
+
ProcessInput input = 2;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
message SendInputResponse {}
|
|
239
|
+
|
|
240
|
+
message ProcessInput {
|
|
241
|
+
oneof input {
|
|
242
|
+
bytes stdin = 1;
|
|
243
|
+
bytes pty = 2;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
message StreamInputRequest {
|
|
248
|
+
oneof event {
|
|
249
|
+
StartEvent start = 1;
|
|
250
|
+
DataEvent data = 2;
|
|
251
|
+
KeepAlive keepalive = 3;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
message StartEvent {
|
|
255
|
+
ProcessSelector process = 1;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
message DataEvent {
|
|
259
|
+
ProcessInput input = 2;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
message KeepAlive {}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
message StreamInputResponse {}
|
|
266
|
+
|
|
267
|
+
enum Signal {
|
|
268
|
+
SIGNAL_UNSPECIFIED = 0;
|
|
269
|
+
SIGNAL_SIGTERM = 15;
|
|
270
|
+
SIGNAL_SIGKILL = 9;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
message SendSignalRequest {
|
|
274
|
+
ProcessSelector process = 1;
|
|
275
|
+
|
|
276
|
+
Signal signal = 2;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
message SendSignalResponse {}
|
|
280
|
+
|
|
281
|
+
message ConnectRequest {
|
|
282
|
+
ProcessSelector process = 1;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
message ProcessSelector {
|
|
286
|
+
oneof selector {
|
|
287
|
+
uint32 pid = 1;
|
|
288
|
+
string tag = 2;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
service ExecutionService {
|
|
293
|
+
// 执行代码接口 (HTTP POST /execute)
|
|
294
|
+
rpc Execute(ExecuteRequest) returns (stream ExecuteResponse) {}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
service ContextService {
|
|
298
|
+
// 创建执行上下文 (HTTP POST /contexts)
|
|
299
|
+
rpc CreateContext(CreateContextRequest) returns (Context) {}
|
|
300
|
+
|
|
301
|
+
// 销毁执行上下文 (HTTP DELETE /contexts/{id})
|
|
302
|
+
rpc DestroyContext(DestroyContextRequest) returns (DestroyContextResponse) {}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// ========== 执行请求 ==========
|
|
306
|
+
message ExecuteRequest {
|
|
307
|
+
string context_id = 1; // 执行上下文ID
|
|
308
|
+
string code = 2; // 要执行的代码
|
|
309
|
+
string language = 3; // 编程语言 (e.g., "python", "javascript")
|
|
310
|
+
map<string, string> env_vars = 4; // 环境变量 (字典格式)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// ========== 流式响应事件 ==========
|
|
314
|
+
message ExecuteResponse {
|
|
315
|
+
oneof event {
|
|
316
|
+
Output stdout = 1; // 标准输出事件
|
|
317
|
+
Output stderr = 2; // 标准错误事件
|
|
318
|
+
Result result = 3; // 最终结果事件
|
|
319
|
+
Error error = 4; // 错误事件
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// 输出内容
|
|
324
|
+
message Output {
|
|
325
|
+
string content = 1; // 输出内容
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// 执行结果
|
|
329
|
+
message Result {
|
|
330
|
+
int32 exit_code = 1; // 进程退出码
|
|
331
|
+
google.protobuf.Timestamp started_at = 2; // 开始时间
|
|
332
|
+
google.protobuf.Timestamp finished_at = 3; // 结束时间
|
|
333
|
+
// 多种输出格式
|
|
334
|
+
string text = 4;
|
|
335
|
+
string html = 5;
|
|
336
|
+
string markdown = 6;
|
|
337
|
+
string svg = 7;
|
|
338
|
+
string png = 8;
|
|
339
|
+
string jpeg = 9;
|
|
340
|
+
string pdf = 10;
|
|
341
|
+
string latex = 11;
|
|
342
|
+
string json = 12;
|
|
343
|
+
string javascript = 13;
|
|
344
|
+
string data = 14;
|
|
345
|
+
Chart chart =15;
|
|
346
|
+
|
|
347
|
+
// 执行计数
|
|
348
|
+
int32 execution_count = 16;
|
|
349
|
+
|
|
350
|
+
// 是否为主要结果
|
|
351
|
+
bool is_main_result = 17;
|
|
352
|
+
|
|
353
|
+
// 额外数据
|
|
354
|
+
map<string, string> extra = 18;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// 错误信息
|
|
358
|
+
message Error {
|
|
359
|
+
string name = 1; // 错误消息
|
|
360
|
+
string value = 2; // 错误类型
|
|
361
|
+
string traceback = 3;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
message Chart {
|
|
365
|
+
string type = 1;
|
|
366
|
+
string title = 2;
|
|
367
|
+
repeated ChartElement elements = 3;
|
|
368
|
+
map<string, string> extra = 4;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
message ChartElement {
|
|
372
|
+
oneof element {
|
|
373
|
+
PointData point_data = 1;
|
|
374
|
+
BarData bar_data = 2;
|
|
375
|
+
PieData pie_data = 3;
|
|
376
|
+
BoxAndWhiskerData box_whisker_data = 4;
|
|
377
|
+
Chart nested_chart = 5;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
message PointData {
|
|
382
|
+
string label = 1;
|
|
383
|
+
repeated Point points = 2;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
message Point {
|
|
387
|
+
oneof x_value {
|
|
388
|
+
string x_str = 1;
|
|
389
|
+
double x_num = 2;
|
|
390
|
+
}
|
|
391
|
+
oneof y_value {
|
|
392
|
+
string y_str = 3;
|
|
393
|
+
double y_num = 4;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
message BarData {
|
|
398
|
+
string label = 1;
|
|
399
|
+
string group = 2;
|
|
400
|
+
string value = 3;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
message PieData {
|
|
404
|
+
string label = 1;
|
|
405
|
+
double angle = 2;
|
|
406
|
+
double radius = 3;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
message BoxAndWhiskerData {
|
|
410
|
+
string label = 1;
|
|
411
|
+
double min = 2;
|
|
412
|
+
double first_quartile = 3;
|
|
413
|
+
double median = 4;
|
|
414
|
+
double third_quartile = 5;
|
|
415
|
+
double max = 6;
|
|
416
|
+
repeated double outliers = 7;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
message Chart2D {
|
|
420
|
+
string x_label = 1;
|
|
421
|
+
string y_label = 2;
|
|
422
|
+
string x_unit = 3;
|
|
423
|
+
string y_unit = 4;
|
|
424
|
+
Chart chart = 5;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
message PointChart {
|
|
428
|
+
repeated string x_ticks = 1;
|
|
429
|
+
repeated string x_tick_labels = 2;
|
|
430
|
+
string x_scale = 3;
|
|
431
|
+
repeated string y_ticks = 4;
|
|
432
|
+
repeated string y_tick_labels = 5;
|
|
433
|
+
string y_scale = 6;
|
|
434
|
+
Chart2D chart_2d = 7;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// ========== 上下文管理 ==========
|
|
438
|
+
// 创建上下文请求
|
|
439
|
+
message CreateContextRequest {
|
|
440
|
+
string language = 1; // 编程语言 (可选)
|
|
441
|
+
string cwd = 2; // 工作目录 (可选)
|
|
442
|
+
// 注意: 根据您的代码,env_vars 未在创建上下文时使用
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// 创建上下文响应
|
|
446
|
+
message Context {
|
|
447
|
+
string id = 1; // 上下文唯一ID
|
|
448
|
+
string language = 2; // 编程语言
|
|
449
|
+
string cwd = 3; // 工作目录
|
|
450
|
+
google.protobuf.Timestamp created_at = 4; // 创建时间
|
|
451
|
+
map<string, string> env_vars = 5; // 当前环境变量
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
message DestroyContextRequest {
|
|
455
|
+
string context_id = 1; // 要销毁的上下文ID
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
message DestroyContextResponse {
|
|
459
|
+
bool success = 1;
|
|
460
|
+
}
|