From 52614e43f0c96ff2340d4017ab26aee38c62a4c4 Mon Sep 17 00:00:00 2001 From: Zuhwa Date: Wed, 31 Dec 2025 16:12:50 +0800 Subject: [PATCH 1/3] Skip x402 payment for zero budget --- virtuals_acp/job.py | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/virtuals_acp/job.py b/virtuals_acp/job.py index d4544c6..8a6eba6 100644 --- a/virtuals_acp/job.py +++ b/virtuals_acp/job.py @@ -154,19 +154,14 @@ def rejection_reason(self) -> Optional[str]: return None request_memo = next( - ( - m - for m in self.memos - if m.next_phase == ACPJobPhase.NEGOTIATION - ), + (m for m in self.memos if m.next_phase == ACPJobPhase.NEGOTIATION), None, ) if request_memo: return request_memo.signed_reason fallback_memo = next( - (m for m in self.memos if m.next_phase == ACPJobPhase.REJECTED), - None + (m for m in self.memos if m.next_phase == ACPJobPhase.REJECTED), None ) return fallback_memo.content if fallback_memo else None @@ -293,9 +288,12 @@ def pay_and_accept_requirement(self, reason: Optional[str] = "") -> str | None: ) ) - x402PaymentDetails = self.acp_contract_client.get_x402_payment_details(self.id) - if x402PaymentDetails.is_x402: - self.perform_x402_payment(self.price) + if self.price > 0: + x402PaymentDetails = self.acp_contract_client.get_x402_payment_details( + self.id + ) + if x402PaymentDetails.is_x402: + self.perform_x402_payment(self.price) response = self.acp_contract_client.handle_operation(operations) return get_txn_hash_from_response(response) @@ -325,7 +323,7 @@ def reject(self, reason: Optional[str] = None) -> str | None: content=memo_content, memo_type=MemoType.MESSAGE, is_secured=True, - next_phase=ACPJobPhase.REJECTED + next_phase=ACPJobPhase.REJECTED, ) ) @@ -347,8 +345,7 @@ def reject_payable( operations.append( self.acp_contract_client.approve_allowance( - amount.amount, - amount.fare.contract_address + amount.amount, amount.fare.contract_address ) ) @@ -520,8 +517,7 @@ def create_payable_notification( operations.append( self.acp_contract_client.approve_allowance( - amount.amount, - amount.fare.contract_address + amount.amount, amount.fare.contract_address ) ) @@ -543,7 +539,7 @@ def create_payable_notification( next_phase=ACPJobPhase.COMPLETED, memo_type=MemoType.PAYABLE_NOTIFICATION, expired_at=expired_at, - token=amount.fare.contract_address + token=amount.fare.contract_address, ) ) @@ -590,7 +586,10 @@ def perform_x402_payment(self, budget: float): self.acp_contract_client.update_job_x402_nonce(self.id, str(nonce)) x402_response = self.acp_contract_client.perform_x402_request( - payment_url, self.acp_contract_client.get_acp_version(), str(budget), encoded_payment + payment_url, + self.acp_contract_client.get_acp_version(), + str(budget), + encoded_payment, ) if x402_response.get("isPaymentRequired"): # If payment is required, submit transfer with authorization and handle the operation From 23a74048029e2828901fe15575d33d65fde0ae55 Mon Sep 17 00:00:00 2001 From: Celeste Ang Date: Mon, 5 Jan 2026 21:30:01 +0900 Subject: [PATCH 2/3] fix: change example expiry time to +5min --- examples/acp_base/skip_evaluation/buyer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/acp_base/skip_evaluation/buyer.py b/examples/acp_base/skip_evaluation/buyer.py index d6d41bd..1e3c925 100644 --- a/examples/acp_base/skip_evaluation/buyer.py +++ b/examples/acp_base/skip_evaluation/buyer.py @@ -87,7 +87,7 @@ def on_new_task(job: ACPJob, memo_to_sign: Optional[ACPMemo] = None): "": "", "": "", }, - expired_at=datetime.now() + timedelta(minutes=3.1), # job expiry duration, minimum 3 minutes + expired_at=datetime.now() + timedelta(minutes=5), # job expiry duration, minimum 3 minutes ) logger.info(f"Job {job_id} initiated") logger.info("Listening for next steps...") From a234bf2ba1376e871d058f12a5c4fdd3aa5a4ad6 Mon Sep 17 00:00:00 2001 From: Celeste Ang Date: Mon, 5 Jan 2026 21:31:22 +0900 Subject: [PATCH 3/3] bump to v0.3.18 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 6d208b5..daa6253 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "virtuals-acp" -version = "0.3.17" +version = "0.3.18" description = "Agent Commerce Protocol Python SDK by Virtuals" authors = ["Steven Lee Soon Fatt "] readme = "README.md"