From a35b53277135d0c4dbf0b82b3fc85182ecd3ce12 Mon Sep 17 00:00:00 2001 From: jxx016 Date: Wed, 30 Apr 2025 19:26:51 -0500 Subject: [PATCH 1/4] fix: better error handling for expired jobs --- plugins/acp/acp_plugin_gamesdk/acp_plugin.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/acp/acp_plugin_gamesdk/acp_plugin.py b/plugins/acp/acp_plugin_gamesdk/acp_plugin.py index cfeff39b..1e97ed98 100644 --- a/plugins/acp/acp_plugin_gamesdk/acp_plugin.py +++ b/plugins/acp/acp_plugin_gamesdk/acp_plugin.py @@ -616,6 +616,10 @@ def _deliver_job_executable(self, jobId: int, deliverableType: str, deliverable: if not job: return FunctionResultStatus.FAILED, "Job not found in your seller jobs - check the ID and verify you're the seller", {} + # Add this check for job expiration + if "expiredAt" in job and job["expiredAt"] and datetime.fromisoformat(job["expiredAt"].replace('Z', '+00:00')) < datetime.now(): + return FunctionResultStatus.FAILED, f"Cannot deliver - this job has expired on {job['expiredAt']}. The buyer may need to create a new job request.", {} + if job["phase"] != AcpJobPhasesDesc.TRANSACTION: return FunctionResultStatus.FAILED, f"Cannot deliver - job is in '{job['phase']}' phase, must be in 'transaction' phase", {} From 5f46ca7c09e41a1dc5e29f97ce6111175cec9746 Mon Sep 17 00:00:00 2001 From: jxx016 Date: Thu, 1 May 2025 16:42:05 -0500 Subject: [PATCH 2/4] changing error handling to UTC --- plugins/acp/acp_plugin_gamesdk/acp_plugin.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/acp/acp_plugin_gamesdk/acp_plugin.py b/plugins/acp/acp_plugin_gamesdk/acp_plugin.py index 1e97ed98..8fadc2b7 100644 --- a/plugins/acp/acp_plugin_gamesdk/acp_plugin.py +++ b/plugins/acp/acp_plugin_gamesdk/acp_plugin.py @@ -617,8 +617,12 @@ def _deliver_job_executable(self, jobId: int, deliverableType: str, deliverable: return FunctionResultStatus.FAILED, "Job not found in your seller jobs - check the ID and verify you're the seller", {} # Add this check for job expiration - if "expiredAt" in job and job["expiredAt"] and datetime.fromisoformat(job["expiredAt"].replace('Z', '+00:00')) < datetime.now(): - return FunctionResultStatus.FAILED, f"Cannot deliver - this job has expired on {job['expiredAt']}. The buyer may need to create a new job request.", {} + if "expiredAt" in job and job["expiredAt"]: + expired_at = datetime.fromisoformat(job["expiredAt"].replace('Z', '+00:00')) + if expired_at < datetime.now(expired_at.tzinfo): + # Format in ISO format to show UTC time, exactly matching the TypeScript version + expired_iso = expired_at.isoformat().replace('+00:00', 'Z') + return FunctionResultStatus.FAILED, f"Cannot deliver - this job has expired on {expired_iso} (UTC). The buyer may need to create a new job request.", {} if job["phase"] != AcpJobPhasesDesc.TRANSACTION: return FunctionResultStatus.FAILED, f"Cannot deliver - job is in '{job['phase']}' phase, must be in 'transaction' phase", {} From ff90cb59a4abd12983cd54b2e4a2bb59847cb5e6 Mon Sep 17 00:00:00 2001 From: jxx016 Date: Thu, 1 May 2025 17:52:42 -0500 Subject: [PATCH 3/4] change to check for cancelled jobs instead --- plugins/acp/acp_plugin_gamesdk/acp_plugin.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/plugins/acp/acp_plugin_gamesdk/acp_plugin.py b/plugins/acp/acp_plugin_gamesdk/acp_plugin.py index 8fadc2b7..5346e7c1 100644 --- a/plugins/acp/acp_plugin_gamesdk/acp_plugin.py +++ b/plugins/acp/acp_plugin_gamesdk/acp_plugin.py @@ -607,6 +607,10 @@ def _deliver_job_executable(self, jobId: int, deliverableType: str, deliverable: try: state = self.get_acp_state() + + # Check if job is cancelled + if any(c["jobId"] == jobId for c in state["jobs"]["cancelled"]): + return FunctionResultStatus.FAILED, "Cannot deliver - this job has been cancelled", {} job = next( (c for c in state["jobs"]["active"]["asASeller"] if c["jobId"] == jobId), @@ -616,14 +620,6 @@ def _deliver_job_executable(self, jobId: int, deliverableType: str, deliverable: if not job: return FunctionResultStatus.FAILED, "Job not found in your seller jobs - check the ID and verify you're the seller", {} - # Add this check for job expiration - if "expiredAt" in job and job["expiredAt"]: - expired_at = datetime.fromisoformat(job["expiredAt"].replace('Z', '+00:00')) - if expired_at < datetime.now(expired_at.tzinfo): - # Format in ISO format to show UTC time, exactly matching the TypeScript version - expired_iso = expired_at.isoformat().replace('+00:00', 'Z') - return FunctionResultStatus.FAILED, f"Cannot deliver - this job has expired on {expired_iso} (UTC). The buyer may need to create a new job request.", {} - if job["phase"] != AcpJobPhasesDesc.TRANSACTION: return FunctionResultStatus.FAILED, f"Cannot deliver - job is in '{job['phase']}' phase, must be in 'transaction' phase", {} From 0595cb6d6c44b614aa562f09a4412d232f40d780 Mon Sep 17 00:00:00 2001 From: jxx016 Date: Fri, 2 May 2025 23:15:46 -0500 Subject: [PATCH 4/4] adding check for respondJob and payJob too --- plugins/acp/acp_plugin_gamesdk/acp_plugin.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/acp/acp_plugin_gamesdk/acp_plugin.py b/plugins/acp/acp_plugin_gamesdk/acp_plugin.py index 5346e7c1..a4222696 100644 --- a/plugins/acp/acp_plugin_gamesdk/acp_plugin.py +++ b/plugins/acp/acp_plugin_gamesdk/acp_plugin.py @@ -428,6 +428,10 @@ def _respond_job_executable(self, jobId: int, decision: str, reasoning: str, twe try: state = self.get_acp_state() + # Check if job is cancelled + if any(c["jobId"] == jobId for c in state["jobs"]["cancelled"]): + return FunctionResultStatus.FAILED, "Cannot respond - this job has been cancelled", {} + job = next( (c for c in state["jobs"]["active"]["asASeller"] if c["jobId"] == jobId), None @@ -514,6 +518,10 @@ def _pay_job_executable(self, jobId: int, amount: float, reasoning: str, tweetCo try: state = self.get_acp_state() + # Check if job is cancelled + if any(c["jobId"] == jobId for c in state["jobs"]["cancelled"]): + return FunctionResultStatus.FAILED, "Cannot pay - this job has been cancelled", {} + job = next( (c for c in state["jobs"]["active"]["asABuyer"] if c["jobId"] == jobId), None