| | |
| | | package com.zy.ai.service; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.AbstractWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.Wrapper; |
| | | import com.zy.ai.domain.autotune.AutoTuneApplyRequest; |
| | | import com.zy.ai.domain.autotune.AutoTuneApplyResult; |
| | |
| | | import com.zy.ai.mcp.service.SpringAiMcpToolManager; |
| | | import com.zy.ai.mcp.tool.AutoTuneMcpTools; |
| | | import com.zy.ai.service.impl.AutoTuneAgentServiceImpl; |
| | | import com.zy.ai.service.impl.AutoTuneControlModeServiceImpl; |
| | | import com.zy.ai.service.impl.AutoTuneCoordinatorServiceImpl; |
| | | import com.zy.asrs.service.WrkMastService; |
| | | import com.zy.common.utils.RedisUtil; |
| | |
| | | import static org.junit.jupiter.api.Assertions.assertEquals; |
| | | import static org.junit.jupiter.api.Assertions.assertFalse; |
| | | import static org.junit.jupiter.api.Assertions.assertNotNull; |
| | | import static org.junit.jupiter.api.Assertions.assertNull; |
| | | import static org.junit.jupiter.api.Assertions.assertSame; |
| | | import static org.junit.jupiter.api.Assertions.assertThrows; |
| | | import static org.junit.jupiter.api.Assertions.assertTrue; |
| | |
| | | import static org.mockito.ArgumentMatchers.anyString; |
| | | import static org.mockito.ArgumentMatchers.eq; |
| | | import static org.mockito.Mockito.doThrow; |
| | | import static org.mockito.Mockito.lenient; |
| | | import static org.mockito.Mockito.never; |
| | | import static org.mockito.Mockito.times; |
| | | import static org.mockito.Mockito.verify; |
| | |
| | | private AiPromptTemplateService aiPromptTemplateService; |
| | | @Mock |
| | | private ConfigService configService; |
| | | private AutoTuneControlModeService autoTuneControlModeService; |
| | | @Mock |
| | | private WrkMastService wrkMastService; |
| | | @Mock |
| | |
| | | |
| | | @BeforeEach |
| | | void setUp() { |
| | | autoTuneControlModeService = new AutoTuneControlModeServiceImpl(configService); |
| | | tools = new AutoTuneMcpTools( |
| | | autoTuneSnapshotService, |
| | | autoTuneApplyService, |
| | | aiAutoTuneJobService, |
| | | aiAutoTuneChangeService, |
| | | aiAutoTuneMcpCallService); |
| | | lenient().when(configService.getConfigValue("aiAutoTuneEnabled", "N")).thenReturn("Y"); |
| | | lenient().when(configService.getConfigValue("aiAutoTuneAnalysisOnly", "Y")).thenReturn("N"); |
| | | } |
| | | |
| | | @Test |
| | |
| | | job.setSummary("applied"); |
| | | job.setSuccessCount(1); |
| | | job.setRejectCount(0); |
| | | AiAutoTuneChange change = new AiAutoTuneChange(); |
| | | change.setJobId(70L); |
| | | change.setTargetType("sys_config"); |
| | | change.setTargetKey("conveyorStationTaskLimit"); |
| | | change.setRequestedValue("12"); |
| | | change.setResultStatus("success"); |
| | | AiAutoTuneChange agentChange = new AiAutoTuneChange(); |
| | | agentChange.setJobId(7L); |
| | | agentChange.setTargetType("station"); |
| | | agentChange.setTargetId("101"); |
| | | agentChange.setTargetKey("outTaskLimit"); |
| | | agentChange.setRequestedValue("3"); |
| | | agentChange.setResultStatus("success"); |
| | | AiAutoTuneChange applyChange = new AiAutoTuneChange(); |
| | | applyChange.setJobId(70L); |
| | | applyChange.setTargetType("sys_config"); |
| | | applyChange.setTargetKey("conveyorStationTaskLimit"); |
| | | applyChange.setRequestedValue("12"); |
| | | applyChange.setResultStatus("success"); |
| | | com.zy.ai.entity.AiAutoTuneMcpCall mcpCall = new com.zy.ai.entity.AiAutoTuneMcpCall(); |
| | | mcpCall.setAgentJobId(7L); |
| | | mcpCall.setCallSeq(1); |
| | |
| | | |
| | | when(aiAutoTuneJobService.list(any(Wrapper.class))).thenReturn(Collections.singletonList(job)); |
| | | when(aiAutoTuneMcpCallService.list(any(Wrapper.class))).thenReturn(Collections.singletonList(mcpCall)); |
| | | when(aiAutoTuneChangeService.list(any(Wrapper.class))).thenReturn(Collections.singletonList(change)); |
| | | List<AiAutoTuneChange> auditChanges = new ArrayList<>(); |
| | | auditChanges.add(agentChange); |
| | | auditChanges.add(applyChange); |
| | | when(aiAutoTuneChangeService.list(any(Wrapper.class))).thenReturn(auditChanges); |
| | | |
| | | List<Map<String, Object>> result = tools.getRecentAutoTuneJobs(99); |
| | | |
| | |
| | | assertFalse(result.get(0).containsKey("reasoningDigest")); |
| | | assertEquals(1, result.get(0).get("mcpCallCount")); |
| | | List<?> changes = (List<?>) result.get(0).get("changes"); |
| | | assertEquals(1, changes.size()); |
| | | assertEquals(2, changes.size()); |
| | | assertEquals(7L, ((Map<?, ?>) changes.get(0)).get("jobId")); |
| | | assertEquals(70L, ((Map<?, ?>) changes.get(1)).get("jobId")); |
| | | |
| | | ArgumentCaptor<Wrapper<AiAutoTuneJob>> wrapperCaptor = ArgumentCaptor.forClass(Wrapper.class); |
| | | verify(aiAutoTuneJobService).list(wrapperCaptor.capture()); |
| | | assertTrue(wrapperCaptor.getValue().getSqlSegment().contains("limit 20")); |
| | | |
| | | ArgumentCaptor<Wrapper<AiAutoTuneChange>> changeWrapperCaptor = ArgumentCaptor.forClass(Wrapper.class); |
| | | verify(aiAutoTuneChangeService).list(changeWrapperCaptor.capture()); |
| | | Wrapper<AiAutoTuneChange> changeWrapper = changeWrapperCaptor.getValue(); |
| | | assertTrue(changeWrapper.getSqlSegment().contains("job_id IN")); |
| | | List<Object> changeQueryParams = wrapperParamValues(changeWrapper); |
| | | assertTrue(changeQueryParams.contains(7L)); |
| | | assertTrue(changeQueryParams.contains(70L)); |
| | | } |
| | | |
| | | @Test |
| | | void recentJobsMarksRollbackMcpChangesAsRollback() { |
| | | AiAutoTuneJob job = new AiAutoTuneJob(); |
| | | job.setId(8L); |
| | | job.setTriggerType("manual"); |
| | | job.setStatus("success"); |
| | | job.setSuccessCount(1); |
| | | job.setRejectCount(0); |
| | | AiAutoTuneChange rollbackChange = new AiAutoTuneChange(); |
| | | rollbackChange.setJobId(80L); |
| | | rollbackChange.setTargetType("sys_config"); |
| | | rollbackChange.setTargetKey("conveyorStationTaskLimit"); |
| | | rollbackChange.setResultStatus("success"); |
| | | com.zy.ai.entity.AiAutoTuneMcpCall mcpCall = new com.zy.ai.entity.AiAutoTuneMcpCall(); |
| | | mcpCall.setAgentJobId(8L); |
| | | mcpCall.setCallSeq(1); |
| | | mcpCall.setToolName("wcs_local_dispatch_revert_last_auto_tune_job"); |
| | | mcpCall.setStatus("success"); |
| | | mcpCall.setApplyJobId(80L); |
| | | mcpCall.setSuccessCount(1); |
| | | |
| | | when(aiAutoTuneJobService.list(any(Wrapper.class))).thenReturn(Collections.singletonList(job)); |
| | | when(aiAutoTuneMcpCallService.list(any(Wrapper.class))).thenReturn(Collections.singletonList(mcpCall)); |
| | | when(aiAutoTuneChangeService.list(any(Wrapper.class))).thenReturn(Collections.singletonList(rollbackChange)); |
| | | |
| | | List<Map<String, Object>> result = tools.getRecentAutoTuneJobs(1); |
| | | |
| | | assertEquals("rollback", result.get(0).get("writeBehavior")); |
| | | List<?> changes = (List<?>) result.get(0).get("changes"); |
| | | assertEquals(1, changes.size()); |
| | | assertEquals("rollback", ((Map<?, ?>) changes.get(0)).get("writeBehavior")); |
| | | } |
| | | |
| | | @Test |
| | |
| | | AutoTuneApplyResult expected = new AutoTuneApplyResult(); |
| | | expected.setDryRun(true); |
| | | expected.setSuccess(true); |
| | | expected.setChanges(Collections.singletonList(applyResultChange("dry_run"))); |
| | | when(autoTuneApplyService.apply(any(AutoTuneApplyRequest.class))).thenReturn(expected); |
| | | |
| | | AutoTuneChangeCommand command = new AutoTuneChangeCommand(); |
| | |
| | | } |
| | | |
| | | @Test |
| | | void applyToolRejectsDuplicateDryRunTargetsBeforeServiceCall() { |
| | | List<AutoTuneChangeCommand> changes = new ArrayList<>(); |
| | | changes.add(change(" sys_config ", "ignored-first", " conveyorStationTaskLimit ", "12")); |
| | | changes.add(change("SYS_CONFIG", "ignored-second", "conveyorStationTaskLimit", "13")); |
| | | |
| | | IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, |
| | | () -> tools.applyAutoTuneChanges("duplicate target", 10, "agent", true, null, changes)); |
| | | |
| | | assertTrue(exception.getMessage().contains("Duplicate auto-tune change target")); |
| | | assertTrue(exception.getMessage().contains("targetType=sys_config")); |
| | | assertTrue(exception.getMessage().contains("targetKey=conveyorStationTaskLimit")); |
| | | verify(autoTuneApplyService, never()).apply(any(AutoTuneApplyRequest.class)); |
| | | } |
| | | |
| | | @Test |
| | | void applyToolRejectsRealApplyWithoutDryRunTokenInAnalysisOnlyMode() { |
| | | AutoTuneChangeCommand command = change("sys_config", null, "conveyorStationTaskLimit", "12"); |
| | | |
| | | IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, |
| | | () -> tools.applyAutoTuneChanges("direct apply", 10, "agent", false, null, |
| | | Collections.singletonList(command))); |
| | | |
| | | assertTrue(exception.getMessage().contains("dryRunToken is required")); |
| | | verify(autoTuneApplyService, never()).apply(any(AutoTuneApplyRequest.class)); |
| | | } |
| | | |
| | | @Test |
| | | void applyToolAllowsRealApplyOnlyWithMatchingDryRunToken() { |
| | | AutoTuneApplyResult dryRunResult = new AutoTuneApplyResult(); |
| | | dryRunResult.setDryRun(true); |
| | | dryRunResult.setSuccess(true); |
| | | dryRunResult.setChanges(Collections.singletonList(applyResultChange("dry_run"))); |
| | | AutoTuneApplyResult applyResult = new AutoTuneApplyResult(); |
| | | applyResult.setDryRun(false); |
| | | applyResult.setSuccess(true); |
| | |
| | | AutoTuneApplyResult dryRunResult = new AutoTuneApplyResult(); |
| | | dryRunResult.setDryRun(true); |
| | | dryRunResult.setSuccess(true); |
| | | dryRunResult.setChanges(Collections.singletonList(applyResultChange("dry_run"))); |
| | | when(autoTuneApplyService.apply(any(AutoTuneApplyRequest.class))).thenReturn(dryRunResult); |
| | | |
| | | AutoTuneApplyResult preview = tools.applyAutoTuneChanges("preview", 10, "agent", true, null, |
| | |
| | | AutoTuneApplyResult dryRunResult = new AutoTuneApplyResult(); |
| | | dryRunResult.setDryRun(true); |
| | | dryRunResult.setSuccess(true); |
| | | dryRunResult.setChanges(Collections.singletonList(applyResultChange("dry_run"))); |
| | | when(autoTuneApplyService.apply(any(AutoTuneApplyRequest.class))).thenReturn(dryRunResult); |
| | | List<AutoTuneChangeCommand> changes = Collections.singletonList( |
| | | change("sys_config", null, "conveyorStationTaskLimit", "12")); |
| | |
| | | } |
| | | |
| | | @Test |
| | | void applyToolDoesNotIssueDryRunTokenWhenAllChangesAreNoChange() { |
| | | AutoTuneApplyResult dryRunResult = new AutoTuneApplyResult(); |
| | | dryRunResult.setDryRun(true); |
| | | dryRunResult.setSuccess(true); |
| | | dryRunResult.setSuccessCount(0); |
| | | dryRunResult.setRejectCount(0); |
| | | dryRunResult.setChanges(Collections.singletonList(applyResultChange("no_change"))); |
| | | when(autoTuneApplyService.apply(any(AutoTuneApplyRequest.class))).thenReturn(dryRunResult); |
| | | |
| | | AutoTuneApplyResult preview = tools.applyAutoTuneChanges("preview", 10, "agent", true, null, |
| | | Collections.singletonList(change("sys_config", null, "conveyorStationTaskLimit", "12"))); |
| | | |
| | | assertNull(preview.getDryRunToken()); |
| | | verify(autoTuneApplyService, times(1)).apply(any(AutoTuneApplyRequest.class)); |
| | | } |
| | | |
| | | @Test |
| | | void rollbackToolDelegatesToApplyServiceRollback() { |
| | | AutoTuneApplyResult expected = new AutoTuneApplyResult(); |
| | | when(autoTuneApplyService.rollbackLastSuccessfulJob("bad result")).thenReturn(expected); |
| | | |
| | | AutoTuneApplyResult result = tools.revertLastAutoTuneJob("bad result"); |
| | | |
| | | assertSame(expected, result); |
| | | verify(autoTuneApplyService).rollbackLastSuccessfulJob("bad result"); |
| | | } |
| | | |
| | | @Test |
| | | void rollbackToolBlocksRollbackInAnalysisOnlyMode() { |
| | | AutoTuneApplyResult expected = new AutoTuneApplyResult(); |
| | | expected.setSuccess(false); |
| | | expected.setAnalysisOnly(true); |
| | | expected.setNoApply(true); |
| | | expected.setRejectCount(1); |
| | | when(autoTuneApplyService.rollbackLastSuccessfulJob("bad result")).thenReturn(expected); |
| | | |
| | | AutoTuneApplyResult result = tools.revertLastAutoTuneJob("bad result"); |
| | |
| | | AutoTuneAgentServiceImpl service = new AutoTuneAgentServiceImpl( |
| | | llmChatService, |
| | | mcpToolManager, |
| | | aiPromptTemplateService); |
| | | aiPromptTemplateService, |
| | | autoTuneControlModeService); |
| | | AiPromptTemplate promptTemplate = new AiPromptTemplate(); |
| | | promptTemplate.setContent("system prompt"); |
| | | when(aiPromptTemplateService.resolvePublished("wcs_auto_tune_dispatch")).thenReturn(promptTemplate); |
| | |
| | | } |
| | | |
| | | @Test |
| | | void agentCallsMcpForRealApplyInAnalysisOnlyMode() { |
| | | when(configService.getConfigValue("aiAutoTuneAnalysisOnly", "Y")).thenReturn("Y"); |
| | | AutoTuneAgentServiceImpl service = agentService(); |
| | | when(mcpToolManager.buildOpenAiTools()).thenReturn(allowedOpenAiTools()); |
| | | when(mcpToolManager.callTool(any(), any(JSONObject.class))).thenAnswer(invocation -> { |
| | | String toolName = invocation.getArgument(0); |
| | | if ("wcs_local_dispatch_apply_auto_tune_changes".equals(toolName)) { |
| | | return rejectedAnalysisOnlyResult(false); |
| | | } |
| | | return Collections.singletonMap("ok", true); |
| | | }); |
| | | when(llmChatService.chatCompletionOrThrow(any(), anyDouble(), anyInt(), any())) |
| | | .thenReturn( |
| | | response("snapshot", toolCall("call_1", "wcs_local_dispatch_get_auto_tune_snapshot", |
| | | "{}"), 10, 5), |
| | | response("apply", toolCall("call_2", "wcs_local_dispatch_apply_auto_tune_changes", |
| | | "{\"dryRun\":false,\"changes\":[{\"targetType\":\"sys_config\",\"targetKey\":\"conveyorStationTaskLimit\",\"newValue\":\"12\"}]}"), 10, 5), |
| | | response("stop", null, 10, 5) |
| | | ); |
| | | |
| | | AutoTuneAgentService.AutoTuneAgentResult result = service.runAutoTune("manual"); |
| | | |
| | | assertFalse(result.getSuccess()); |
| | | assertTrue(result.getAnalysisOnly()); |
| | | assertFalse(result.getAllowApply()); |
| | | assertEquals("analysis_only", result.getExecutionMode()); |
| | | assertFalse(result.getActualApplyCalled()); |
| | | assertEquals(1, result.getRejectCount()); |
| | | assertTrue(result.getSummary().contains("仅分析模式禁止实际应用/回滚")); |
| | | verify(mcpToolManager).callTool(eq("wcs_local_dispatch_get_auto_tune_snapshot"), any(JSONObject.class)); |
| | | verify(mcpToolManager).callTool(eq("wcs_local_dispatch_apply_auto_tune_changes"), any(JSONObject.class)); |
| | | } |
| | | |
| | | @Test |
| | | void agentCallsMcpForRollbackInAnalysisOnlyMode() { |
| | | when(configService.getConfigValue("aiAutoTuneAnalysisOnly", "Y")).thenReturn("Y"); |
| | | AutoTuneAgentServiceImpl service = agentService(); |
| | | when(mcpToolManager.buildOpenAiTools()).thenReturn(allowedOpenAiTools()); |
| | | when(mcpToolManager.callTool(any(), any(JSONObject.class))).thenAnswer(invocation -> { |
| | | String toolName = invocation.getArgument(0); |
| | | if ("wcs_local_dispatch_revert_last_auto_tune_job".equals(toolName)) { |
| | | return rejectedAnalysisOnlyResult(false); |
| | | } |
| | | return Collections.singletonMap("ok", true); |
| | | }); |
| | | when(llmChatService.chatCompletionOrThrow(any(), anyDouble(), anyInt(), any())) |
| | | .thenReturn( |
| | | response("snapshot", toolCall("call_1", "wcs_local_dispatch_get_auto_tune_snapshot", |
| | | "{}"), 10, 5), |
| | | response("rollback", toolCall("call_2", "wcs_local_dispatch_revert_last_auto_tune_job", |
| | | "{\"reason\":\"bad result\"}"), 10, 5), |
| | | response("stop", null, 10, 5) |
| | | ); |
| | | |
| | | AutoTuneAgentService.AutoTuneAgentResult result = service.runAutoTune("manual"); |
| | | |
| | | assertFalse(result.getSuccess()); |
| | | assertTrue(result.getAnalysisOnly()); |
| | | assertTrue(result.getRollbackCalled()); |
| | | assertEquals(1, result.getRejectCount()); |
| | | assertTrue(result.getSummary().contains("仅分析模式禁止实际应用/回滚")); |
| | | verify(mcpToolManager).callTool(eq("wcs_local_dispatch_get_auto_tune_snapshot"), any(JSONObject.class)); |
| | | verify(mcpToolManager).callTool(eq("wcs_local_dispatch_revert_last_auto_tune_job"), any(JSONObject.class)); |
| | | } |
| | | |
| | | @Test |
| | | void agentMarksSnapshotOnlyRunAsNoActualMutationEvenIfAssistantClaimsApplied() { |
| | | AutoTuneAgentServiceImpl service = agentService(); |
| | | when(mcpToolManager.buildOpenAiTools()).thenReturn(allowedOpenAiTools()); |
| | |
| | | assertFalse(result.getActualApplyCalled()); |
| | | assertFalse(result.getRollbackCalled()); |
| | | assertEquals(0, result.getSuccessCount()); |
| | | assertTrue(result.getSummary().startsWith("自动调参 Agent 未调用实际应用或回滚工具,未修改运行参数。")); |
| | | assertTrue(result.getSummary().contains("自动调参 Agent 未调用实际应用或回滚工具,未修改运行参数。")); |
| | | } |
| | | |
| | | @Test |
| | | void agentDoesNotMarkNoChangeRealApplyAsActualApplyWhenSuccessCountIsPositive() { |
| | | AutoTuneAgentServiceImpl service = agentService(); |
| | | when(mcpToolManager.buildOpenAiTools()).thenReturn(allowedOpenAiTools()); |
| | | when(mcpToolManager.callTool(any(), any(JSONObject.class))).thenAnswer(invocation -> { |
| | | String toolName = invocation.getArgument(0); |
| | | if ("wcs_local_dispatch_apply_auto_tune_changes".equals(toolName)) { |
| | | LinkedHashMap<String, Object> noChange = new LinkedHashMap<>(); |
| | | noChange.put("resultStatus", "no_change"); |
| | | |
| | | LinkedHashMap<String, Object> applyOutput = new LinkedHashMap<>(); |
| | | applyOutput.put("success", true); |
| | | applyOutput.put("dryRun", false); |
| | | applyOutput.put("successCount", 1); |
| | | applyOutput.put("rejectCount", 0); |
| | | applyOutput.put("changes", Collections.singletonList(noChange)); |
| | | return applyOutput; |
| | | } |
| | | return Collections.singletonMap("ok", true); |
| | | }); |
| | | when(llmChatService.chatCompletionOrThrow(any(), anyDouble(), anyInt(), any())) |
| | | .thenReturn( |
| | | response("snapshot", toolCall("call_1", "wcs_local_dispatch_get_auto_tune_snapshot", |
| | | "{}"), 10, 5), |
| | | response("apply no change", toolCall("call_2", "wcs_local_dispatch_apply_auto_tune_changes", |
| | | "{\"dryRun\":false,\"dryRunToken\":\"token-123\",\"changes\":[{\"targetType\":\"sys_config\",\"targetKey\":\"conveyorStationTaskLimit\",\"newValue\":\"12\"}]}"), 10, 5), |
| | | response("无变更", null, 10, 5) |
| | | ); |
| | | |
| | | AutoTuneAgentService.AutoTuneAgentResult result = service.runAutoTune("manual"); |
| | | |
| | | assertTrue(result.getSuccess()); |
| | | assertFalse(result.getActualApplyCalled()); |
| | | assertEquals(1, result.getSuccessCount()); |
| | | assertEquals(0, result.getRejectCount()); |
| | | } |
| | | |
| | | @Test |
| | |
| | | AiPromptTemplate promptTemplate = new AiPromptTemplate(); |
| | | promptTemplate.setContent("system prompt"); |
| | | when(aiPromptTemplateService.resolvePublished("wcs_auto_tune_dispatch")).thenReturn(promptTemplate); |
| | | return new AutoTuneAgentServiceImpl(llmChatService, mcpToolManager, aiPromptTemplateService); |
| | | return new AutoTuneAgentServiceImpl( |
| | | llmChatService, |
| | | mcpToolManager, |
| | | aiPromptTemplateService, |
| | | autoTuneControlModeService); |
| | | } |
| | | |
| | | private AutoTuneCoordinatorServiceImpl coordinatorService() { |
| | | return new AutoTuneCoordinatorServiceImpl( |
| | | configService, |
| | | autoTuneControlModeService, |
| | | wrkMastService, |
| | | aiAutoTuneJobService, |
| | | aiAutoTuneMcpCallService, |
| | |
| | | return result; |
| | | } |
| | | |
| | | private AutoTuneApplyResult rejectedAnalysisOnlyResult(Boolean dryRun) { |
| | | AutoTuneApplyResult result = new AutoTuneApplyResult(); |
| | | result.setDryRun(dryRun); |
| | | result.setSuccess(false); |
| | | result.setAnalysisOnly(true); |
| | | result.setNoApply(true); |
| | | result.setSuccessCount(0); |
| | | result.setRejectCount(1); |
| | | result.setSummary("仅分析模式禁止实际应用/回滚,未修改运行参数"); |
| | | result.setChanges(new ArrayList<>()); |
| | | return result; |
| | | } |
| | | |
| | | private AutoTuneChangeCommand change(String targetType, String targetId, String targetKey, String newValue) { |
| | | AutoTuneChangeCommand command = new AutoTuneChangeCommand(); |
| | | command.setTargetType(targetType); |
| | |
| | | return command; |
| | | } |
| | | |
| | | private AiAutoTuneChange applyResultChange(String resultStatus) { |
| | | AiAutoTuneChange change = new AiAutoTuneChange(); |
| | | change.setResultStatus(resultStatus); |
| | | return change; |
| | | } |
| | | |
| | | private List<Object> wrapperParamValues(Wrapper<?> wrapper) { |
| | | if (!(wrapper instanceof AbstractWrapper<?, ?, ?> abstractWrapper)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | return new ArrayList<>(abstractWrapper.getParamNameValuePairs().values()); |
| | | } |
| | | |
| | | private List<Object> allowedOpenAiTools() { |
| | | List<Object> tools = new ArrayList<>(); |
| | | tools.add(openAiTool("wcs_local_dispatch_get_auto_tune_snapshot")); |