acp-plugin-gamesdk 0.1.1__py3-none-any.whl → 0.1.3__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.
- acp_plugin_gamesdk/acp_client.py +20 -32
- acp_plugin_gamesdk/acp_plugin.py +11 -11
- acp_plugin_gamesdk/acp_token.py +36 -43
- acp_plugin_gamesdk/interface.py +6 -1
- {acp_plugin_gamesdk-0.1.1.dist-info → acp_plugin_gamesdk-0.1.3.dist-info}/METADATA +2 -2
- acp_plugin_gamesdk-0.1.3.dist-info/RECORD +8 -0
- acp_plugin_gamesdk-0.1.1.dist-info/RECORD +0 -8
- {acp_plugin_gamesdk-0.1.1.dist-info → acp_plugin_gamesdk-0.1.3.dist-info}/WHEEL +0 -0
acp_plugin_gamesdk/acp_client.py
CHANGED
@@ -2,20 +2,18 @@ from datetime import datetime, timedelta
|
|
2
2
|
from typing import List, Optional
|
3
3
|
from web3 import Web3
|
4
4
|
import requests
|
5
|
-
import
|
6
|
-
import
|
7
|
-
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../")))
|
8
|
-
from .interface import AcpAgent, AcpJobPhases, AcpState
|
9
|
-
from .acp_token import AcpToken, MemoType
|
5
|
+
from acp_plugin_gamesdk.interface import AcpAgent, AcpJobPhases, AcpOffering, AcpState
|
6
|
+
from acp_plugin_gamesdk.acp_token import AcpToken, MemoType
|
10
7
|
import time
|
11
8
|
|
12
9
|
|
13
10
|
class AcpClient:
|
14
|
-
def __init__(self, api_key: str, acp_token: AcpToken):
|
11
|
+
def __init__(self, api_key: str, acp_token: AcpToken, acp_base_url: Optional[str] = None):
|
15
12
|
self.base_url = "https://sdk-dev.game.virtuals.io/acp"
|
16
13
|
self.api_key = api_key
|
17
14
|
self.acp_token = acp_token
|
18
15
|
self.web3 = Web3()
|
16
|
+
self.acp_base_url = acp_base_url if acp_base_url else "https://acpx-staging.virtuals.io/api"
|
19
17
|
|
20
18
|
@property
|
21
19
|
def agent_wallet_address(self) -> str:
|
@@ -29,16 +27,17 @@ class AcpClient:
|
|
29
27
|
return response.json()
|
30
28
|
|
31
29
|
def browse_agents(self, cluster: Optional[str] = None, query: Optional[str] = None) -> List[AcpAgent]:
|
32
|
-
url = "
|
30
|
+
url = f"{self.acp_base_url}/agents"
|
33
31
|
|
34
|
-
params = {}
|
35
32
|
if query:
|
36
|
-
|
33
|
+
url += f"?search={requests.utils.quote(query)}"
|
37
34
|
|
38
35
|
if cluster:
|
39
|
-
|
36
|
+
# Add & if there's already a parameter, otherwise add ?
|
37
|
+
separator = "&" if query else "?"
|
38
|
+
url += f"{separator}filters[cluster]={requests.utils.quote(cluster)}"
|
40
39
|
|
41
|
-
response = requests.get(url
|
40
|
+
response = requests.get(url)
|
42
41
|
|
43
42
|
if response.status_code != 200:
|
44
43
|
raise Exception(f"Failed to browse agents: {response.text}")
|
@@ -49,24 +48,25 @@ class AcpClient:
|
|
49
48
|
|
50
49
|
for agent in response_json.get("data", []):
|
51
50
|
result.append(
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
51
|
+
AcpAgent(
|
52
|
+
id=agent["id"],
|
53
|
+
name=agent["name"],
|
54
|
+
description=agent["description"],
|
55
|
+
wallet_address=agent["walletAddress"],
|
56
|
+
offerings=[AcpOffering(name=offering["name"], price=offering["price"]) for offering in agent["offerings"]]
|
57
|
+
)
|
58
58
|
)
|
59
59
|
|
60
60
|
return result
|
61
61
|
|
62
62
|
def create_job(self, provider_address: str, price: float, job_description: str) -> int:
|
63
63
|
expire_at = datetime.now() + timedelta(days=1)
|
64
|
-
|
65
64
|
tx_result = self.acp_token.create_job(
|
66
65
|
provider_address=provider_address,
|
67
66
|
evaluator_address=provider_address,
|
68
67
|
expire_at=expire_at
|
69
68
|
)
|
69
|
+
|
70
70
|
job_id = None
|
71
71
|
retry_count = 3
|
72
72
|
retry_delay = 3
|
@@ -74,7 +74,7 @@ class AcpClient:
|
|
74
74
|
time.sleep(retry_delay)
|
75
75
|
for attempt in range(retry_count):
|
76
76
|
try:
|
77
|
-
response = self.acp_token.
|
77
|
+
response = self.acp_token.validate_transaction(tx_result["txHash"])
|
78
78
|
data = response.get("data", {})
|
79
79
|
if not data:
|
80
80
|
raise Exception("Invalid tx_hash!")
|
@@ -133,7 +133,6 @@ class AcpClient:
|
|
133
133
|
def response_job(self, job_id: int, accept: bool, memo_id: int, reasoning: str):
|
134
134
|
if accept:
|
135
135
|
self.acp_token.sign_memo(memo_id, accept, reasoning)
|
136
|
-
|
137
136
|
time.sleep(5)
|
138
137
|
|
139
138
|
return self.acp_token.create_memo(
|
@@ -162,7 +161,7 @@ class AcpClient:
|
|
162
161
|
time.sleep(5)
|
163
162
|
return self.acp_token.sign_memo(memo_id, True, reason)
|
164
163
|
|
165
|
-
def deliver_job(self, job_id: int, deliverable: str
|
164
|
+
def deliver_job(self, job_id: int, deliverable: str):
|
166
165
|
return self.acp_token.create_memo(
|
167
166
|
job_id=int(job_id),
|
168
167
|
content=deliverable,
|
@@ -172,17 +171,6 @@ class AcpClient:
|
|
172
171
|
)
|
173
172
|
|
174
173
|
def add_tweet(self, job_id: int, tweet_id: str, content: str):
|
175
|
-
"""
|
176
|
-
Add a tweet to a job.
|
177
|
-
|
178
|
-
Args:
|
179
|
-
job_id: The ID of the job
|
180
|
-
tweet_id: The ID of the tweet
|
181
|
-
content: The content of the tweet
|
182
|
-
|
183
|
-
Raises:
|
184
|
-
Exception: If the request fails
|
185
|
-
"""
|
186
174
|
payload = {
|
187
175
|
"tweetId": tweet_id,
|
188
176
|
"content": content
|
acp_plugin_gamesdk/acp_plugin.py
CHANGED
@@ -5,13 +5,11 @@ from datetime import datetime
|
|
5
5
|
|
6
6
|
from game_sdk.game.agent import WorkerConfig
|
7
7
|
from game_sdk.game.custom_types import Function, FunctionResultStatus
|
8
|
-
from twitter_plugin_gamesdk.twitter_plugin import TwitterPlugin
|
9
|
-
|
10
8
|
from twitter_plugin_gamesdk.twitter_plugin import TwitterPlugin
|
11
9
|
from twitter_plugin_gamesdk.game_twitter_plugin import GameTwitterPlugin
|
12
|
-
from .acp_client import AcpClient
|
13
|
-
from .acp_token import AcpToken
|
14
|
-
from .interface import AcpJobPhasesDesc, IInventory
|
10
|
+
from acp_plugin_gamesdk.acp_client import AcpClient
|
11
|
+
from acp_plugin_gamesdk.acp_token import AcpToken
|
12
|
+
from acp_plugin_gamesdk.interface import AcpJobPhasesDesc, IInventory
|
15
13
|
|
16
14
|
@dataclass
|
17
15
|
class AcpPluginOptions:
|
@@ -19,12 +17,13 @@ class AcpPluginOptions:
|
|
19
17
|
acp_token_client: AcpToken
|
20
18
|
twitter_plugin: TwitterPlugin | GameTwitterPlugin = None
|
21
19
|
cluster: Optional[str] = None
|
20
|
+
acp_base_url: Optional[str] = None
|
21
|
+
|
22
22
|
|
23
23
|
class AcpPlugin:
|
24
24
|
def __init__(self, options: AcpPluginOptions):
|
25
25
|
print("Initializing AcpPlugin")
|
26
|
-
self.acp_client = AcpClient(options.api_key, options.acp_token_client)
|
27
|
-
|
26
|
+
self.acp_client = AcpClient(options.api_key, options.acp_token_client, options.acp_base_url)
|
28
27
|
self.id = "acp_worker"
|
29
28
|
self.name = "ACP Worker"
|
30
29
|
self.description = """
|
@@ -45,6 +44,9 @@ class AcpPlugin:
|
|
45
44
|
self.cluster = options.cluster
|
46
45
|
self.twitter_plugin = options.twitter_plugin
|
47
46
|
self.produced_inventory: List[IInventory] = []
|
47
|
+
self.acp_base_url = options.acp_base_url if options.acp_base_url else "https://acpx-staging.virtuals.io/api"
|
48
|
+
|
49
|
+
|
48
50
|
|
49
51
|
def add_produce_item(self, item: IInventory) -> None:
|
50
52
|
self.produced_inventory.append(item)
|
@@ -108,9 +110,9 @@ class AcpPlugin:
|
|
108
110
|
|
109
111
|
if not agents:
|
110
112
|
return FunctionResultStatus.FAILED, "No other trading agents found in the system. Please try again later when more agents are available.", {}
|
111
|
-
|
113
|
+
|
112
114
|
return FunctionResultStatus.DONE, json.dumps({
|
113
|
-
"availableAgents": agents,
|
115
|
+
"availableAgents": [{"id": agent.id, "name": agent.name, "description": agent.description, "wallet_address": agent.wallet_address, "offerings": [{"name": offering.name, "price": offering.price} for offering in agent.offerings]} for agent in agents],
|
114
116
|
"totalAgentsFound": len(agents),
|
115
117
|
"timestamp": datetime.now().timestamp(),
|
116
118
|
"note": "Use the walletAddress when initiating a job with your chosen trading partner."
|
@@ -439,8 +441,6 @@ class AcpPlugin:
|
|
439
441
|
self.acp_client.deliver_job(
|
440
442
|
int(jobId),
|
441
443
|
json.dumps(deliverable),
|
442
|
-
job["memo"][0]["id"],
|
443
|
-
reasoning
|
444
444
|
)
|
445
445
|
|
446
446
|
if (self.twitter_plugin is not None):
|
acp_plugin_gamesdk/acp_token.py
CHANGED
@@ -4,10 +4,7 @@ from typing import Optional, Tuple, TypedDict
|
|
4
4
|
from datetime import datetime
|
5
5
|
from web3 import Web3
|
6
6
|
from eth_account import Account
|
7
|
-
import
|
8
|
-
import os
|
9
|
-
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../")))
|
10
|
-
from .acp_token_abi import ACP_TOKEN_ABI
|
7
|
+
from acp_plugin_gamesdk.acp_token_abi import ACP_TOKEN_ABI
|
11
8
|
import requests
|
12
9
|
from eth_account.messages import encode_defunct
|
13
10
|
import json
|
@@ -48,9 +45,9 @@ class AcpToken:
|
|
48
45
|
wallet_private_key: str,
|
49
46
|
agent_wallet_address: str,
|
50
47
|
network_url: str,
|
48
|
+
acp_base_url: Optional[str] = None,
|
51
49
|
contract_address: str = "0x2422c1c43451Eb69Ff49dfD39c4Dc8C5230fA1e6",
|
52
50
|
virtuals_token_address: str = "0xbfAB80ccc15DF6fb7185f9498d6039317331846a",
|
53
|
-
base_url: str = "https://acpx.virtuals.gg/api"
|
54
51
|
):
|
55
52
|
self.web3 = Web3(Web3.HTTPProvider(network_url))
|
56
53
|
self.account = Account.from_key(wallet_private_key)
|
@@ -88,21 +85,19 @@ class AcpToken:
|
|
88
85
|
"type": "function"
|
89
86
|
}]
|
90
87
|
)
|
91
|
-
self.
|
92
|
-
|
88
|
+
self.acp_base_url = acp_base_url if acp_base_url else "https://acpx-staging.virtuals.io/api"
|
93
89
|
def get_agent_wallet_address(self) -> str:
|
94
90
|
return self.agent_wallet_address
|
95
91
|
|
96
92
|
def get_contract_address(self) -> str:
|
97
93
|
return self.contract_address
|
98
94
|
|
99
|
-
def
|
95
|
+
def validate_transaction(self, hash_value: str) -> object:
|
100
96
|
try:
|
101
|
-
response = requests.post(f"{self.
|
97
|
+
response = requests.post(f"{self.acp_base_url}/acp-agent-wallets/trx-result", json={"userOpHash": hash_value})
|
102
98
|
return response.json()
|
103
99
|
except Exception as error:
|
104
|
-
|
105
|
-
raise Exception("Failed to get job_id")
|
100
|
+
raise Exception(f"Failed to get job_id {error}")
|
106
101
|
|
107
102
|
def create_job(
|
108
103
|
self,
|
@@ -128,15 +123,18 @@ class AcpToken:
|
|
128
123
|
}
|
129
124
|
|
130
125
|
# Submit to custom API
|
131
|
-
api_url = f"{self.
|
126
|
+
api_url = f"{self.acp_base_url}/acp-agent-wallets/transactions"
|
132
127
|
response = requests.post(api_url, json=payload)
|
133
|
-
|
128
|
+
|
129
|
+
|
130
|
+
if response.json().get("error"):
|
131
|
+
raise Exception(f"Failed to create job {response.json().get('error').get('status')}, Message: {response.json().get('error').get('message')}")
|
132
|
+
|
134
133
|
# Return transaction hash or response ID
|
135
|
-
return {
|
134
|
+
return {"txHash": response.json().get("data", {}).get("userOpHash", "")}
|
136
135
|
|
137
136
|
except Exception as error:
|
138
|
-
|
139
|
-
raise Exception("Failed to create job")
|
137
|
+
raise Exception(f"{error}")
|
140
138
|
|
141
139
|
def approve_allowance(self, price_in_wei: int) -> str:
|
142
140
|
try:
|
@@ -152,16 +150,15 @@ class AcpToken:
|
|
152
150
|
"signature": signature
|
153
151
|
}
|
154
152
|
|
155
|
-
api_url = f"{self.
|
153
|
+
api_url = f"{self.acp_base_url}/acp-agent-wallets/transactions"
|
156
154
|
response = requests.post(api_url, json=payload)
|
157
155
|
|
158
|
-
if (response.
|
159
|
-
raise Exception("Failed to approve allowance")
|
156
|
+
if (response.json().get("error")):
|
157
|
+
raise Exception(f"Failed to approve allowance {response.json().get('error').get('status')}, Message: {response.json().get('error').get('message')}")
|
160
158
|
|
161
159
|
return response.json()
|
162
160
|
except Exception as error:
|
163
|
-
|
164
|
-
raise Exception("Failed to approve allowance")
|
161
|
+
raise Exception(f"{error}")
|
165
162
|
|
166
163
|
def create_memo(
|
167
164
|
self,
|
@@ -185,19 +182,19 @@ class AcpToken:
|
|
185
182
|
"signature": signature
|
186
183
|
}
|
187
184
|
|
188
|
-
api_url = f"{self.
|
185
|
+
api_url = f"{self.acp_base_url}/acp-agent-wallets/transactions"
|
189
186
|
response = requests.post(api_url, json=payload)
|
190
187
|
|
191
|
-
if (response.
|
192
|
-
raise Exception("Failed to create memo")
|
188
|
+
if (response.json().get("error")):
|
189
|
+
raise Exception(f"Failed to create memo {response.json().get('error').get('status')}, Message: {response.json().get('error').get('message')}")
|
193
190
|
|
194
191
|
return { "txHash": response.json().get("txHash", response.json().get("id", "")), "memoId": response.json().get("memoId", "")}
|
195
192
|
except Exception as error:
|
196
|
-
print(f"
|
193
|
+
print(f"{error}")
|
197
194
|
retries -= 1
|
198
195
|
time.sleep(2 * (3 - retries))
|
199
196
|
|
200
|
-
raise Exception("
|
197
|
+
raise Exception(f"{error}")
|
201
198
|
|
202
199
|
def _sign_transaction(self, method_name: str, args: list, contract_address: Optional[str] = None) -> Tuple[dict, str]:
|
203
200
|
if contract_address:
|
@@ -240,20 +237,20 @@ class AcpToken:
|
|
240
237
|
"signature": signature
|
241
238
|
}
|
242
239
|
|
243
|
-
api_url = f"{self.
|
240
|
+
api_url = f"{self.acp_base_url}/acp-agent-wallets/transactions"
|
244
241
|
response = requests.post(api_url, json=payload)
|
245
242
|
|
246
|
-
if (response.
|
247
|
-
raise Exception("Failed to sign memo")
|
243
|
+
if (response.json().get("error")):
|
244
|
+
raise Exception(f"Failed to sign memo {response.json().get('error').get('status')}, Message: {response.json().get('error').get('message')}")
|
248
245
|
|
249
|
-
return response.json()
|
246
|
+
return response.json()
|
250
247
|
|
251
248
|
except Exception as error:
|
252
|
-
print(f"
|
249
|
+
print(f"{error}")
|
253
250
|
retries -= 1
|
254
251
|
time.sleep(2 * (3 - retries))
|
255
252
|
|
256
|
-
raise Exception("Failed to sign memo")
|
253
|
+
raise Exception(f"Failed to sign memo {error}")
|
257
254
|
|
258
255
|
def set_budget(self, job_id: int, budget: int) -> str:
|
259
256
|
try:
|
@@ -268,16 +265,15 @@ class AcpToken:
|
|
268
265
|
"signature": signature
|
269
266
|
}
|
270
267
|
|
271
|
-
api_url = f"{self.
|
268
|
+
api_url = f"{self.acp_base_url}/acp-agent-wallets/transactions"
|
272
269
|
response = requests.post(api_url, json=payload)
|
273
270
|
|
274
|
-
if (response.
|
275
|
-
raise Exception("Failed to set budget")
|
271
|
+
if (response.json().get("error")):
|
272
|
+
raise Exception(f"Failed to set budget {response.json().get('error').get('status')}, Message: {response.json().get('error').get('message')}")
|
276
273
|
|
277
274
|
return response.json()
|
278
275
|
except Exception as error:
|
279
|
-
|
280
|
-
raise Exception("Failed to set budget")
|
276
|
+
raise Exception(f"{error}")
|
281
277
|
|
282
278
|
def get_job(self, job_id: int) -> Optional[IJob]:
|
283
279
|
try:
|
@@ -298,8 +294,7 @@ class AcpToken:
|
|
298
294
|
'evaluatorCount': int(job_data[8])
|
299
295
|
}
|
300
296
|
except Exception as error:
|
301
|
-
|
302
|
-
raise Exception("Failed to get job")
|
297
|
+
raise Exception(f"{error}")
|
303
298
|
|
304
299
|
def get_memo_by_job(
|
305
300
|
self,
|
@@ -315,8 +310,7 @@ class AcpToken:
|
|
315
310
|
else:
|
316
311
|
return memos[-1] if memos else None
|
317
312
|
except Exception as error:
|
318
|
-
|
319
|
-
raise Exception("Failed to get memo")
|
313
|
+
raise Exception(f"Failed to get memo by job {error}")
|
320
314
|
|
321
315
|
def get_memos_for_phase(
|
322
316
|
self,
|
@@ -330,5 +324,4 @@ class AcpToken:
|
|
330
324
|
target_memos = [m for m in memos if m['nextPhase'] == target_phase]
|
331
325
|
return target_memos[-1] if target_memos else None
|
332
326
|
except Exception as error:
|
333
|
-
|
334
|
-
raise Exception("Failed to get memos")
|
327
|
+
raise Exception(f"Failed to get memos for phase {error}")
|
acp_plugin_gamesdk/interface.py
CHANGED
@@ -2,13 +2,18 @@ from dataclasses import dataclass
|
|
2
2
|
from enum import IntEnum, Enum
|
3
3
|
from typing import List, Dict
|
4
4
|
|
5
|
+
@dataclass
|
6
|
+
class AcpOffering:
|
7
|
+
name: str
|
8
|
+
price: float
|
5
9
|
@dataclass
|
6
10
|
class AcpAgent:
|
7
11
|
id: str
|
8
12
|
name: str
|
9
13
|
description: str
|
10
14
|
wallet_address: str
|
11
|
-
|
15
|
+
offerings: List[AcpOffering]
|
16
|
+
|
12
17
|
class AcpJobPhases(IntEnum):
|
13
18
|
REQUEST = 0
|
14
19
|
NEGOTIATION = 1
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: acp-plugin-gamesdk
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.3
|
4
4
|
Summary: ACP Plugin for Python SDK for GAME by Virtuals
|
5
5
|
Author: Steven Lee Soon Fatt
|
6
6
|
Author-email: steven@virtuals.io
|
@@ -109,7 +109,7 @@ acp_plugin = AcpPlugin(
|
|
109
109
|
```
|
110
110
|
|
111
111
|
> Note:
|
112
|
-
> - Your
|
112
|
+
> - Your agent wallet address for your buyer and seller should be different.
|
113
113
|
> - Speak to a DevRel (Celeste/John) to get a GAME Dev API key
|
114
114
|
|
115
115
|
> To Whitelist your Wallet:
|
@@ -0,0 +1,8 @@
|
|
1
|
+
acp_plugin_gamesdk/acp_client.py,sha256=1mHE6h3E4DET-INSxw6O5REAX1drRpiAxphJt1EFxxQ,7320
|
2
|
+
acp_plugin_gamesdk/acp_plugin.py,sha256=Cr7fsTXIeaww9CENmx0KPN65lf6KRir-n8jpVPi5ksE,20288
|
3
|
+
acp_plugin_gamesdk/acp_token.py,sha256=CL-0Ww1i0tzDNj0sAuY3DvlWIKrEGoMcb0Z69e5X9og,11720
|
4
|
+
acp_plugin_gamesdk/acp_token_abi.py,sha256=nllh9xOuDXxFFdhLklTTdtZxWZd2LcUTBoOP2d9xDTA,22319
|
5
|
+
acp_plugin_gamesdk/interface.py,sha256=HxGHUc1VhdTGpFNk1JDwwb9n73IZdI08iDJttB0qB_s,1353
|
6
|
+
acp_plugin_gamesdk-0.1.3.dist-info/METADATA,sha256=aHLfn_gLmFaKjyJrvzzIQ90UoZfmX9SK_bu7giWn1Bo,9691
|
7
|
+
acp_plugin_gamesdk-0.1.3.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
8
|
+
acp_plugin_gamesdk-0.1.3.dist-info/RECORD,,
|
@@ -1,8 +0,0 @@
|
|
1
|
-
acp_plugin_gamesdk/acp_client.py,sha256=FK-7M2ZvVwhMkz8Gv5AX6-1dmHjwFwOTjLLiIHsz5x0,7283
|
2
|
-
acp_plugin_gamesdk/acp_plugin.py,sha256=6FZ3v3SPzRJohElgKYkH63IrBMK0qLw0LnIr_kTzRm8,19972
|
3
|
-
acp_plugin_gamesdk/acp_token.py,sha256=JdxwyZonlEa71ik-dtw5EVYGUvNlIW-tkeeKb7htzug,11550
|
4
|
-
acp_plugin_gamesdk/acp_token_abi.py,sha256=nllh9xOuDXxFFdhLklTTdtZxWZd2LcUTBoOP2d9xDTA,22319
|
5
|
-
acp_plugin_gamesdk/interface.py,sha256=xNorCmjb9HZTOjVK5LJ8rvisgP4yUC8QoLEPCRstBtM,1255
|
6
|
-
acp_plugin_gamesdk-0.1.1.dist-info/METADATA,sha256=QO-zYSCN6fSSGjD73kc3JQCHhTfSg2xiPDLEO2-GxEo,9680
|
7
|
-
acp_plugin_gamesdk-0.1.1.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
8
|
-
acp_plugin_gamesdk-0.1.1.dist-info/RECORD,,
|
File without changes
|