Skip to content

Commit 1d30e40

Browse files
authored
fix(backend): Charge user credits before its block execution (#9427)
### Changes 🏗️ Instead of letting the user to execution the block then break it post-execution. We can charge the user first and execute it afterward. The trade-offs: * We can't charge a block that is charged based on the execution time. * We will also charge failed block executions. ### Checklist 📋 #### For code changes: - [ ] I have clearly listed my changes in the PR description - [ ] I have made a test plan - [ ] I have tested my changes according to the test plan: <!-- Put your test plan here: --> - [ ] ... <details> <summary>Example test plan</summary> - [ ] Create from scratch and execute an agent with at least 3 blocks - [ ] Import an agent from file upload, and confirm it executes correctly - [ ] Upload agent to marketplace - [ ] Import an agent from marketplace and confirm it executes correctly - [ ] Edit an agent from monitor, and confirm it executes correctly </details> #### For configuration changes: - [ ] `.env.example` is updated or already compatible with my changes - [ ] `docker-compose.yml` is updated or already compatible with my changes - [ ] I have included a list of my configuration changes in the PR description (under **Changes**) <details> <summary>Examples of configuration changes</summary> - Changing ports - Adding new services that need to communicate with each other - Secrets or environment variable changes - New or infrastructure changes such as databases </details>
1 parent 22536de commit 1d30e40

File tree

2 files changed

+8
-11
lines changed

2 files changed

+8
-11
lines changed

autogpt_platform/backend/backend/data/credit.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ async def _add_transaction(
232232

233233
if amount < 0 and user_balance < abs(amount):
234234
raise ValueError(
235-
f"Insufficient balance for user {user_id}, balance: {user_balance}, amount: {amount}"
235+
f"Insufficient balance of ${user_balance/100} to run the block that costs ${abs(amount)/100}"
236236
)
237237

238238
# Create the transaction

autogpt_platform/backend/backend/executor/manager.py

+7-10
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ def update_execution(status: ExecutionStatus) -> ExecutionResult:
163163
# AgentExecutorBlock specially separate the node input_data & its input_default.
164164
if isinstance(node_block, AgentExecutorBlock):
165165
input_data = {**node.input_default, "data": input_data}
166+
data.data = input_data
166167

167168
# Execute the node
168169
input_data_str = json.dumps(input_data)
@@ -192,6 +193,11 @@ def update_execution(status: ExecutionStatus) -> ExecutionResult:
192193

193194
output_size = 0
194195
try:
196+
# Charge the user for the execution before running the block.
197+
# TODO: We assume the block is executed within 0 seconds.
198+
# This is fine because for now, there is no block that is charged by time.
199+
db_client.spend_credits(data, input_size + output_size, 0)
200+
195201
for output_name, output_data in node_block.execute(
196202
input_data, **extra_exec_kwargs
197203
):
@@ -210,16 +216,7 @@ def update_execution(status: ExecutionStatus) -> ExecutionResult:
210216
):
211217
yield execution
212218

213-
# Update execution status and spend credits
214-
res = update_execution(ExecutionStatus.COMPLETED)
215-
s = input_size + output_size
216-
t = (
217-
(res.end_time - res.start_time).total_seconds()
218-
if res.end_time and res.start_time
219-
else 0
220-
)
221-
data.data = input_data
222-
db_client.spend_credits(data, s, t)
219+
update_execution(ExecutionStatus.COMPLETED)
223220

224221
except Exception as e:
225222
error_msg = str(e)

0 commit comments

Comments
 (0)