Commit 78976885fd5b86de869db65c7a1acba8ec59376d

Authored by YunaiV
1 parent edffc819

fix(ai1): 对齐消息页顺序并兼容 JDK 17

yudao-module-ai1-springai/src/main/java/cn/iocoder/yudao/module/ai1/controller/admin/session/Ai1SessionMessageController.java
... ... @@ -77,7 +77,7 @@ public class Ai1SessionMessageController {
77 77 // ==================== 管理 ====================
78 78  
79 79 @GetMapping("/page")
80   - @Operation(summary = "获得会话消息分页", description = "按消息编号倒序")
  80 + @Operation(summary = "获得会话消息分页", description = "按消息编号倒序取最新页,页内按时间正序")
81 81 @PreAuthorize("@ss.hasPermission('ai1:session:query')")
82 82 public CommonResult<PageResult<Ai1SessionMessageRespVO>> getSessionMessagePage(@Valid Ai1SessionMessagePageReqVO pageReqVO) {
83 83 return success(BeanUtils.toBean(sessionMessageService.getSessionMessagePage(pageReqVO),
... ...
yudao-module-ai1-springai/src/main/java/cn/iocoder/yudao/module/ai1/harness/session/Ai1SessionStreamTool.java
... ... @@ -529,7 +529,7 @@ public class Ai1SessionStreamTool implements SmartLifecycle {
529 529 if (!lock.tryLock()) {
530 530 return false;
531 531 }
532   - long ownerThreadId = Thread.currentThread().threadId();
  532 + long ownerThreadId = Thread.currentThread().getId();
533 533 try {
534 534 // 3. 锁内重新读取,期间可能已被 worker 完成
535 535 Ai1SessionMessageDO current = sessionMessageService.getSessionMessage(messageId);
... ... @@ -687,7 +687,7 @@ public class Ai1SessionStreamTool implements SmartLifecycle {
687 687 if (!lock.tryLock()) {
688 688 return;
689 689 }
690   - long workerThreadId = Thread.currentThread().threadId();
  690 + long workerThreadId = Thread.currentThread().getId();
691 691 try {
692 692 Long tenantId = Convert.toLong(fields.get(FIELD_TENANT_ID));
693 693 TenantUtils.execute(tenantId, () -> executeTask(recordId, fields, messageId, lock, workerThreadId, reclaimed));
... ...
yudao-module-ai1-springai/src/main/java/cn/iocoder/yudao/module/ai1/service/session/Ai1SessionMessageService.java
... ... @@ -26,7 +26,7 @@ public interface Ai1SessionMessageService {
26 26 List<Ai1SessionMessageDO> getSessionMessageListBySessionId(Long sessionId);
27 27  
28 28 /**
29   - * 获得会话消息分页,按编号倒序
  29 + * 获得会话消息分页,按编号倒序取最新页,页内按时间正序
30 30 *
31 31 * @param pageReqVO 分页查询
32 32 * @return 消息分页
... ...
yudao-module-ai1-springai/src/main/java/cn/iocoder/yudao/module/ai1/service/session/Ai1SessionMessageServiceImpl.java
... ... @@ -63,7 +63,12 @@ public class Ai1SessionMessageServiceImpl implements Ai1SessionMessageService {
63 63  
64 64 @Override
65 65 public PageResult<Ai1SessionMessageDO> getSessionMessagePage(Ai1SessionMessagePageReqVO pageReqVO) {
66   - return sessionMessageMapper.selectPage(pageReqVO);
  66 + PageResult<Ai1SessionMessageDO> pageResult = sessionMessageMapper.selectPage(pageReqVO);
  67 + // 按编号倒序取最新页,页内反转为时间正序
  68 + if (CollUtil.isNotEmpty(pageResult.getList())) {
  69 + Collections.reverse(pageResult.getList());
  70 + }
  71 + return pageResult;
67 72 }
68 73  
69 74 @Override
... ...
yudao-module-ai1-springai/src/test/java/cn/iocoder/yudao/module/ai1/harness/mcp/Ai1McpToolFactoryTest.java
... ... @@ -67,7 +67,7 @@ public class Ai1McpToolFactoryTest extends BaseMockitoUnitTest {
67 67 // 调用
68 68 List<ToolCallback> callbacks = buildTools(List.of(mcp), List.of("search"));
69 69 // 断言
70   - assertEquals("github__search", callbacks.getFirst().getToolDefinition().name());
  70 + assertEquals("github__search", callbacks.get(0).getToolDefinition().name());
71 71 }
72 72  
73 73 @Test
... ... @@ -78,8 +78,8 @@ public class Ai1McpToolFactoryTest extends BaseMockitoUnitTest {
78 78 // 调用
79 79 List<ToolCallback> callbacks = buildTools(List.of(mcp), List.of("search"));
80 80 // 断言
81   - assertEquals("a".repeat(56) + "__search", callbacks.getFirst().getToolDefinition().name());
82   - assertEquals(64, callbacks.getFirst().getToolDefinition().name().length());
  81 + assertEquals("a".repeat(56) + "__search", callbacks.get(0).getToolDefinition().name());
  82 + assertEquals(64, callbacks.get(0).getToolDefinition().name().length());
83 83 }
84 84  
85 85 @Test
... ... @@ -127,7 +127,7 @@ public class Ai1McpToolFactoryTest extends BaseMockitoUnitTest {
127 127 List<ToolCallback> callbacks = buildTools(List.of(mcp), List.of(toolName));
128 128  
129 129 // 调用
130   - String result = callbacks.getFirst().call("{\"query\":\"北京\"}");
  130 + String result = callbacks.get(0).call("{\"query\":\"北京\"}");
131 131 // 断言
132 132 assertEquals("搜索结果", JsonUtils.parseObject(result, String.class));
133 133 verify(mcpClientTool).callTool(mcp, toolName, arguments);
... ...
yudao-module-ai1-springai/src/test/java/cn/iocoder/yudao/module/ai1/service/session/Ai1SessionMessageServiceImplTest.java
... ... @@ -171,11 +171,25 @@ public class Ai1SessionMessageServiceImplTest extends BaseDbUnitTest {
171 171  
172 172 // 调用
173 173 PageResult<Ai1SessionMessageDO> pageResult = sessionMessageService.getSessionMessagePage(reqVO);
174   - // 断言:按编号倒序
  174 + // 断言:取最新一页,页内按时间正序
175 175 assertEquals(3, pageResult.getTotal());
176   - assertEquals(List.of(message3.getId(), message2.getId()),
  176 + assertEquals(List.of(message2.getId(), message3.getId()),
177 177 pageResult.getList().stream().map(Ai1SessionMessageDO::getId).toList());
178   - assertNotEquals(message1.getId(), pageResult.getList().get(1).getId());
  178 +
  179 + // 调用:第二页
  180 + reqVO.setPageNo(2);
  181 + pageResult = sessionMessageService.getSessionMessagePage(reqVO);
  182 + // 断言:更早的消息
  183 + assertEquals(3, pageResult.getTotal());
  184 + assertEquals(List.of(message1.getId()),
  185 + pageResult.getList().stream().map(Ai1SessionMessageDO::getId).toList());
  186 +
  187 + // 调用:超出范围的空页
  188 + reqVO.setPageNo(3);
  189 + pageResult = sessionMessageService.getSessionMessagePage(reqVO);
  190 + // 断言
  191 + assertEquals(3, pageResult.getTotal());
  192 + assertTrue(pageResult.getList().isEmpty());
179 193 }
180 194  
181 195 @Test
... ...