@@ -96,126 +96,117 @@ public function execute(ImplementIssueMessage $message): void
9696
9797 private function doExecute (ImplementIssueMessage $ message , ProductConfigDto $ config ): void
9898 {
99- $ runStarted = $ this ->workflowConcurrencyFacade ->tryStartRun (
99+ $ didRun = $ this ->workflowConcurrencyFacade ->executeWithRunClaim (
100100 $ message ->productConfigId ,
101101 $ message ->issueNumber ,
102102 WorkflowRunPhase::Implementation,
103103 $ message ->runId ,
104- );
105-
106- if (!$ runStarted ) {
107- $ this ->logger ->info ('[ImplementationAgent] Skipping stale or duplicate implementation message ' , [
108- 'productConfigId ' => $ message ->productConfigId ,
109- 'issueNumber ' => $ message ->issueNumber ,
110- 'runId ' => $ message ->runId ,
111- ]);
112-
113- return ;
114- }
104+ function () use ($ message , $ config ): void {
105+ $ issueDto = $ this ->findIssue ($ config ->githubUrl , $ config ->githubToken , $ message ->issueNumber );
106+ if ($ issueDto === null ) {
107+ $ this ->logger ->error ('[ImplementationAgent] Could not fetch issue data ' , [
108+ 'issueNumber ' => $ message ->issueNumber ,
109+ ]);
110+
111+ return ;
112+ }
115113
116- try {
117- $ issueDto = $ this ->findIssue ($ config ->githubUrl , $ config ->githubToken , $ message ->issueNumber );
118- if ($ issueDto === null ) {
119- $ this ->logger ->error ('[ImplementationAgent] Could not fetch issue data ' , [
120- 'issueNumber ' => $ message ->issueNumber ,
121- ]);
114+ $ issueComments = $ this ->githubIntegrationFacade ->getIssueComments (
115+ $ config ->githubUrl ,
116+ $ config ->githubToken ,
117+ $ message ->issueNumber ,
118+ );
122119
123- return ;
124- }
120+ $ workspaceInfo = null ;
121+
122+ try {
123+ if ($ message ->isRevision && $ message ->prBranchName !== null ) {
124+ $ workspaceInfo = $ this ->workspaceManagementFacade ->acquireWorkspace (
125+ $ config ->id ,
126+ $ message ->issueNumber ,
127+ $ config ->githubUrl ,
128+ $ config ->githubToken ,
129+ $ message ->prBranchName ,
130+ );
131+
132+ $ prComments = $ message ->prNumber !== null
133+ ? $ this ->githubIntegrationFacade ->getPullRequestComments ($ config ->githubUrl , $ config ->githubToken , $ message ->prNumber )
134+ : [];
135+
136+ $ prompt = $ this ->buildRevisionPrompt ($ issueDto , $ issueComments , $ prComments , $ message ->prNumber );
137+ } else {
138+ $ workspaceInfo = $ this ->workspaceManagementFacade ->acquireWorkspace (
139+ $ config ->id ,
140+ $ message ->issueNumber ,
141+ $ config ->githubUrl ,
142+ $ config ->githubToken ,
143+ );
144+
145+ $ prompt = $ this ->buildPrompt ($ issueDto , $ issueComments );
146+ }
147+
148+ $ agentApiKeyOverride = $ message ->agentApiKeyOverride ;
149+ $ credentials = $ agentApiKeyOverride !== null
150+ ? new AgentCredentialsDto ($ agentApiKeyOverride , $ agentApiKeyOverride )
151+ : new AgentCredentialsDto ($ config ->cursorAgentApiKey , $ config ->anthropicApiKey );
152+
153+ $ agentResult = $ this ->llmIntegrationFacade ->runAgent (
154+ AgentRole::Implementation,
155+ $ prompt ,
156+ $ workspaceInfo ->workspacePath ,
157+ $ credentials ,
158+ $ config ->githubToken ,
159+ $ workspaceInfo ->containerName ,
160+ $ message ->agentProviderOverride ,
161+ );
125162
126- $ issueComments = $ this ->githubIntegrationFacade ->getIssueComments (
127- $ config ->githubUrl ,
128- $ config ->githubToken ,
129- $ message ->issueNumber ,
130- );
163+ $ outcome = ImplementationOutcome::fromAgentOutput ($ agentResult ->success , $ agentResult ->resultText );
131164
132- $ workspaceInfo = null ;
165+ $ this ->logger ->info ('[ImplementationAgent] Agent completed ' , [
166+ 'issueNumber ' => $ message ->issueNumber ,
167+ 'outcome ' => $ outcome ->value ,
168+ 'isRevision ' => $ message ->isRevision ,
169+ 'durationMs ' => $ agentResult ->durationMs ,
170+ ]);
133171
134- try {
135- if ($ message ->isRevision && $ message ->prBranchName !== null ) {
136- $ workspaceInfo = $ this ->workspaceManagementFacade ->acquireWorkspace (
137- $ config ->id ,
138- $ message ->issueNumber ,
172+ $ this ->handleOutcome (
173+ $ outcome ,
174+ $ agentResult ->resultText ,
139175 $ config ->githubUrl ,
140176 $ config ->githubToken ,
141- $ message ->prBranchName ,
177+ $ message ->issueNumber ,
178+ $ issueDto ,
179+ $ message ->prNumber ,
142180 );
181+ } catch (Throwable $ e ) {
182+ $ this ->logger ->error ('[ImplementationAgent] Unhandled exception ' , [
183+ 'issueNumber ' => $ message ->issueNumber ,
184+ 'isRevision ' => $ message ->isRevision ,
185+ 'error ' => $ e ->getMessage (),
186+ ]);
143187
144- $ prComments = $ message ->prNumber !== null
145- ? $ this ->githubIntegrationFacade ->getPullRequestComments ($ config ->githubUrl , $ config ->githubToken , $ message ->prNumber )
146- : [];
188+ $ this ->applyErrorLabels ($ config ->githubUrl , $ config ->githubToken , $ message ->issueNumber );
147189
148- $ prompt = $ this ->buildRevisionPrompt ($ issueDto , $ issueComments , $ prComments , $ message ->prNumber );
149- } else {
150- $ workspaceInfo = $ this ->workspaceManagementFacade ->acquireWorkspace (
151- $ config ->id ,
152- $ message ->issueNumber ,
190+ $ this ->githubIntegrationFacade ->postIssueComment (
153191 $ config ->githubUrl ,
154192 $ config ->githubToken ,
193+ $ message ->issueNumber ,
194+ "**ProductBuilder Implementation Error** \n\nAn unexpected error occurred during implementation: \n\n> " . $ e ->getMessage (),
155195 );
156-
157- $ prompt = $ this ->buildPrompt ($ issueDto , $ issueComments );
196+ } finally {
197+ if ($ workspaceInfo !== null ) {
198+ $ this ->workspaceManagementFacade ->releaseWorkspace ($ workspaceInfo );
199+ }
158200 }
201+ },
202+ );
159203
160- $ agentApiKeyOverride = $ message ->agentApiKeyOverride ;
161- $ credentials = $ agentApiKeyOverride !== null
162- ? new AgentCredentialsDto ($ agentApiKeyOverride , $ agentApiKeyOverride )
163- : new AgentCredentialsDto ($ config ->cursorAgentApiKey , $ config ->anthropicApiKey );
164-
165- $ agentResult = $ this ->llmIntegrationFacade ->runAgent (
166- AgentRole::Implementation,
167- $ prompt ,
168- $ workspaceInfo ->workspacePath ,
169- $ credentials ,
170- $ config ->githubToken ,
171- $ workspaceInfo ->containerName ,
172- $ message ->agentProviderOverride ,
173- );
174-
175- $ outcome = ImplementationOutcome::fromAgentOutput ($ agentResult ->success , $ agentResult ->resultText );
176-
177- $ this ->logger ->info ('[ImplementationAgent] Agent completed ' , [
178- 'issueNumber ' => $ message ->issueNumber ,
179- 'outcome ' => $ outcome ->value ,
180- 'isRevision ' => $ message ->isRevision ,
181- 'durationMs ' => $ agentResult ->durationMs ,
182- ]);
183-
184- $ this ->handleOutcome (
185- $ outcome ,
186- $ agentResult ->resultText ,
187- $ config ->githubUrl ,
188- $ config ->githubToken ,
189- $ message ->issueNumber ,
190- $ issueDto ,
191- $ message ->prNumber ,
192- );
193- } catch (Throwable $ e ) {
194- $ this ->logger ->error ('[ImplementationAgent] Unhandled exception ' , [
195- 'issueNumber ' => $ message ->issueNumber ,
196- 'isRevision ' => $ message ->isRevision ,
197- 'error ' => $ e ->getMessage (),
198- ]);
199-
200- $ this ->applyErrorLabels ($ config ->githubUrl , $ config ->githubToken , $ message ->issueNumber );
201-
202- $ this ->githubIntegrationFacade ->postIssueComment (
203- $ config ->githubUrl ,
204- $ config ->githubToken ,
205- $ message ->issueNumber ,
206- "**ProductBuilder Implementation Error** \n\nAn unexpected error occurred during implementation: \n\n> " . $ e ->getMessage (),
207- );
208- } finally {
209- if ($ workspaceInfo !== null ) {
210- $ this ->workspaceManagementFacade ->releaseWorkspace ($ workspaceInfo );
211- }
212- }
213- } finally {
214- $ this ->workflowConcurrencyFacade ->releaseRunClaim (
215- $ message ->productConfigId ,
216- $ message ->issueNumber ,
217- $ message ->runId ,
218- );
204+ if (!$ didRun ) {
205+ $ this ->logger ->info ('[ImplementationAgent] Skipping stale or duplicate implementation message ' , [
206+ 'productConfigId ' => $ message ->productConfigId ,
207+ 'issueNumber ' => $ message ->issueNumber ,
208+ 'runId ' => $ message ->runId ,
209+ ]);
219210 }
220211 }
221212
0 commit comments