Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (C) 2026 github.com/MaloneTalk
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
* limitations under the License.
*/
package io.github.malonetalk.agent.tools;

import io.agentscope.core.tool.Tool;
import io.github.malonetalk.service.DomainService;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@AllArgsConstructor
public class GetDomainsTool implements MarkAgentTool {

private final DomainService domainService;

@Tool(
name = "get_domains",
description =
"Get available data domains in the datasource. Call this tool first to discover"
+ " what domains are available before querying tables.")
public List<String> getDomains() {
return domainService.listDomainNames();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package io.github.malonetalk.agent.tools;

import io.agentscope.core.tool.Tool;
import io.agentscope.core.tool.ToolParam;
import io.github.malonetalk.entity.Datasource;
import io.github.malonetalk.entity.TableInfo;
import io.github.malonetalk.enums.Status;
Expand All @@ -37,8 +38,22 @@ public class GetTablesTool implements MarkAgentTool {
private final DatasourceService dataSourceService;
private final TableSemanticService tableSemanticService;

@Tool(name = "get_tables", description = "获取数据库中的表信息,包括表名和表描述")
public List<TableInfo> getTables() {
@Tool(
name = "get_tables",
description =
"Get table information from the database, including table name and description."
+ " Optionally filter by domains; returns all tables if domains is not"
+ " provided. It is recommended to call get_domains first to discover"
+ " available domains.")
public List<TableInfo> getTables(
@ToolParam(
name = "domains",
description =
"Optional list of domain names. Only tables belonging to these"
+ " domains will be returned. If not provided or empty,"
+ " returns all tables.",
required = false)
List<String> domains) {
List<Datasource> activeDataSources =
dataSourceService.findByStatus(Status.ACTIVE.getCode());

Expand All @@ -54,6 +69,6 @@ public List<TableInfo> getTables() {
}

Datasource dataSource = activeDataSources.get(0);
return tableSemanticService.listTableInfosByDatasourceId(dataSource.getId());
return tableSemanticService.listTableInfosByDomains(dataSource.getId(), domains);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public final class SemanticConstants {
public static final String RELATION_KEY_SEPARATOR = "|";
public static final String SORT_ORDER_ASC = "asc";
public static final String SORT_ORDER_DESC = "desc";
public static final String DEFAULT_DOMAIN = "default";

private SemanticConstants() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/
package io.github.malonetalk.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;
Expand Down Expand Up @@ -66,4 +67,9 @@ public DataSource dataSource() {

return new HikariDataSource(config);
}

@Bean
public ObjectMapper objectMapper() {
return new ObjectMapper();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (C) 2026 github.com/MaloneTalk
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
* limitations under the License.
*/
package io.github.malonetalk.controller;

import io.github.malonetalk.common.Result;
import io.github.malonetalk.dto.DomainCreateRequest;
import io.github.malonetalk.dto.DomainPageQuery;
import io.github.malonetalk.dto.DomainUpdateRequest;
import io.github.malonetalk.dto.pagination.PageResponse;
import io.github.malonetalk.entity.DomainInfo;
import io.github.malonetalk.service.DomainService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/domains")
@RequiredArgsConstructor
public class DomainController {

private final DomainService domainService;

@GetMapping
public Result<PageResponse<DomainInfo>> findDomains(@Valid DomainPageQuery query) {
return Result.success(domainService.getDomainPage(query));
}

@GetMapping("/{id}")
public Result<DomainInfo> findById(@PathVariable Integer id) {
Comment thread
mengnankkkk marked this conversation as resolved.
if (id == null || id < 0) {
return Result.error(400, "ID必须为非负数");
}
DomainInfo domain = domainService.findById(id);
if (domain == null) {
return Result.error(404, "领域不存在");
}
return Result.success(domain);
}

@PostMapping
public Result<DomainInfo> create(@Valid @RequestBody DomainCreateRequest request) {
return Result.success(domainService.create(request));
}

@PutMapping("/{id}")
public Result<DomainInfo> update(
@PathVariable Integer id, @Valid @RequestBody DomainUpdateRequest request) {
if (id == null || id < 0) {
return Result.error(400, "ID必须为非负数");
}
return Result.success(domainService.update(id, request));
}

@DeleteMapping("/{id}")
public Result<Boolean> delete(@PathVariable Integer id) {
if (id == null || id < 0) {
return Result.error(400, "ID必须为非负数");
}
domainService.delete(id);
return Result.success(true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (C) 2026 github.com/MaloneTalk
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
* limitations under the License.
*/
package io.github.malonetalk.dto;

import jakarta.validation.constraints.NotBlank;

public record DomainCreateRequest(
@NotBlank(message = "领域名称不能为空") String name, String description) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2026 github.com/MaloneTalk
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
* limitations under the License.
*/
package io.github.malonetalk.dto;

import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.Pattern;

public record DomainPageQuery(
@Min(1) Integer page,
@Min(1) Integer pageSize,
String keyword,
@Pattern(regexp = "^(?i)(asc|desc)$", message = "sortOrder must be asc or desc.")
String sortOrder) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (C) 2026 github.com/MaloneTalk
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
* limitations under the License.
*/
package io.github.malonetalk.dto;

import jakarta.validation.constraints.NotBlank;

public record DomainUpdateRequest(
@NotBlank(message = "领域名称不能为空") String name, String description) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2026 github.com/MaloneTalk
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
* limitations under the License.
*/
package io.github.malonetalk.entity;

import java.time.LocalDateTime;
import lombok.Data;

@Data
public class DomainInfo {

private Integer id;
private String name;
private String description;
private LocalDateTime createTime;
private LocalDateTime updateTime;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2026 github.com/MaloneTalk
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
* limitations under the License.
*/
package io.github.malonetalk.mapper;

import io.github.malonetalk.dto.DomainPageQuery;
import io.github.malonetalk.entity.DomainInfo;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

@Mapper
public interface DomainInfoMapper {

int insert(DomainInfo domainInfo);

int update(DomainInfo domainInfo);

int deleteByIds(@Param("ids") List<Integer> ids);

List<DomainInfo> selectAll();

List<DomainInfo> selectPage(
@Param("query") DomainPageQuery query, @Param("sortDescending") boolean sortDescending);

DomainInfo selectById(@Param("id") Integer id);

DomainInfo selectByName(@Param("name") String name);
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,9 @@ List<TableInfo> selectPageByDatasourceId(

TableInfo selectByDatasourceIdAndTableName(
@Param("datasourceId") Integer datasourceId, @Param("tableName") String tableName);

List<TableInfo> selectByDatasourceIdAndDomains(
@Param("datasourceId") Integer datasourceId, @Param("domains") List<String> domains);

int countByDomain(@Param("domain") String domain);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (C) 2026 github.com/MaloneTalk
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
* limitations under the License.
*/
package io.github.malonetalk.service;

import io.github.malonetalk.dto.DomainCreateRequest;
import io.github.malonetalk.dto.DomainPageQuery;
import io.github.malonetalk.dto.DomainUpdateRequest;
import io.github.malonetalk.dto.pagination.PageResponse;
import io.github.malonetalk.entity.DomainInfo;
import java.util.List;

public interface DomainService {

PageResponse<DomainInfo> getDomainPage(DomainPageQuery query);

DomainInfo findById(Integer id);

DomainInfo create(DomainCreateRequest request);

DomainInfo update(Integer id, DomainUpdateRequest request);

void delete(Integer id);

List<String> listDomainNames();
}
Loading
Loading