Deduplicate chat tool query patterns

This commit is contained in:
2026-06-21 13:51:44 +02:00
parent 3b14c1ecf3
commit d3e2397217
2 changed files with 58 additions and 69 deletions

View File

@@ -28,6 +28,7 @@ after each item.
- [x] `generation/renderers.ex` - [x] `generation/renderers.ex`
- [x] `mcp/tools.ex` - [x] `mcp/tools.ex`
- [x] `mcp/server.ex` - [x] `mcp/server.ex`
- [x] `ai/chat_tools.ex`
--- ---

View File

@@ -59,16 +59,7 @@ defmodule BDS.AI.ChatTools do
def execute("search_posts", arguments, project_id) do def execute("search_posts", arguments, project_id) do
project_id = project_id || active_project_id() project_id = project_id || active_project_id()
filters = search_filters(arguments) filters = search_filters(arguments)
search_result(project_id, arguments["query"] || "", filters, &Queries.post_summary/1)
{:ok, result} = Search.search_posts(project_id, arguments["query"] || "", filters)
%{
posts: Enum.map(result.posts, &Queries.post_summary/1),
total: result.total,
offset: result.offset,
limit: result.limit,
has_more: result.offset + result.limit < result.total
}
end end
def execute("read_post_by_slug", arguments, project_id) do def execute("read_post_by_slug", arguments, project_id) do
@@ -83,13 +74,9 @@ defmodule BDS.AI.ChatTools do
def execute("read_post", arguments, project_id) do def execute("read_post", arguments, project_id) do
project_id = project_id || active_project_id() project_id = project_id || active_project_id()
case Repo.get_by(Post, with_post(arguments, project_id, %{success: false, error: "not_found"}, fn post ->
id: arguments["postId"] || arguments["post_id"], %{post: Queries.post_detail(post)}
project_id: project_id end)
) do
%Post{} = post -> %{post: Queries.post_detail(post)}
nil -> %{success: false, error: "not_found"}
end
end end
def execute("list_posts", arguments, project_id) do def execute("list_posts", arguments, project_id) do
@@ -98,21 +85,12 @@ defmodule BDS.AI.ChatTools do
offset = normalize_offset(arguments["offset"]) offset = normalize_offset(arguments["offset"])
filters = search_filters(arguments) |> Map.merge(%{limit: limit, offset: offset}) filters = search_filters(arguments) |> Map.merge(%{limit: limit, offset: offset})
{:ok, result} = Search.search_posts(project_id, "", filters) search_result(project_id, "", filters, fn post ->
%{
posts:
Enum.map(result.posts, fn post ->
post post
|> Queries.post_summary() |> Queries.post_summary()
|> Map.put("url", "/posts/#{post.slug}") |> Map.put("url", "/posts/#{post.slug}")
|> Map.put("updated_at", post.updated_at) |> Map.put("updated_at", post.updated_at)
end), end)
total: result.total,
offset: result.offset,
limit: result.limit,
has_more: result.offset + result.limit < result.total
}
end end
def execute("list_media", arguments, project_id) do def execute("list_media", arguments, project_id) do
@@ -138,13 +116,9 @@ defmodule BDS.AI.ChatTools do
def execute("get_media", arguments, project_id) do def execute("get_media", arguments, project_id) do
project_id = project_id || active_project_id() project_id = project_id || active_project_id()
case Repo.get_by(Media, with_media(arguments, project_id, %{success: false, error: "not_found"}, fn media ->
id: arguments["mediaId"] || arguments["media_id"], %{media: media_summary(media)}
project_id: project_id end)
) do
%Media{} = media -> %{media: media_summary(media)}
nil -> %{success: false, error: "not_found"}
end
end end
def execute("view_image", arguments, project_id) do def execute("view_image", arguments, project_id) do
@@ -235,51 +209,33 @@ defmodule BDS.AI.ChatTools do
def execute("get_post_backlinks", arguments, project_id) do def execute("get_post_backlinks", arguments, project_id) do
project_id = project_id || active_project_id() project_id = project_id || active_project_id()
case Repo.get_by(Post, with_post(arguments, project_id, %{success: false, error: "not_found"}, fn post ->
id: arguments["postId"] || arguments["post_id"],
project_id: project_id
) do
%Post{} = post ->
%{success: true, post_id: post.id, linked_by: Queries.linked_posts(post.id, :incoming)} %{success: true, post_id: post.id, linked_by: Queries.linked_posts(post.id, :incoming)}
end)
nil ->
%{success: false, error: "not_found"}
end
end end
def execute("get_post_outlinks", arguments, project_id) do def execute("get_post_outlinks", arguments, project_id) do
project_id = project_id || active_project_id() project_id = project_id || active_project_id()
case Repo.get_by(Post, with_post(arguments, project_id, %{success: false, error: "not_found"}, fn post ->
id: arguments["postId"] || arguments["post_id"],
project_id: project_id
) do
%Post{} = post ->
%{success: true, post_id: post.id, links_to: Queries.linked_posts(post.id, :outgoing)} %{success: true, post_id: post.id, links_to: Queries.linked_posts(post.id, :outgoing)}
end)
nil ->
%{success: false, error: "not_found"}
end
end end
def execute("get_post_media", arguments, project_id) do def execute("get_post_media", arguments, project_id) do
project_id = project_id || active_project_id() project_id = project_id || active_project_id()
post_id = arguments["postId"] || arguments["post_id"]
case Repo.get_by(Post, id: post_id, project_id: project_id) do with_post(arguments, project_id, %{success: false, error: "not_found"}, fn post ->
%Post{} = post -> %{success: true, post_id: post.id, media: post_media(project_id, post.id)} %{success: true, post_id: post.id, media: post_media(project_id, post.id)}
nil -> %{success: false, error: "not_found"} end)
end
end end
def execute("get_media_posts", arguments, project_id) do def execute("get_media_posts", arguments, project_id) do
project_id = project_id || active_project_id() project_id = project_id || active_project_id()
media_id = arguments["mediaId"] || arguments["media_id"]
case Repo.get_by(Media, id: media_id, project_id: project_id) do with_media(arguments, project_id, %{success: false, error: "not_found"}, fn media ->
%Media{} = media -> %{success: true, media_id: media.id, posts: media_posts(media.id)} %{success: true, media_id: media.id, posts: media_posts(media.id)}
nil -> %{success: false, error: "not_found"} end)
end
end end
def execute("render_table", arguments, _project_id) do def execute("render_table", arguments, _project_id) do
@@ -1007,6 +963,38 @@ defmodule BDS.AI.ChatTools do
result result
end end
defp search_result(project_id, query, filters, mapper) do
{:ok, result} = Search.search_posts(project_id, query, filters)
%{
posts: Enum.map(result.posts, mapper),
total: result.total,
offset: result.offset,
limit: result.limit,
has_more: result.offset + result.limit < result.total
}
end
defp with_post(arguments, project_id, not_found_result, success_fun) do
case Repo.get_by(Post,
id: arguments["postId"] || arguments["post_id"],
project_id: project_id
) do
%Post{} = post -> success_fun.(post)
nil -> not_found_result
end
end
defp with_media(arguments, project_id, not_found_result, success_fun) do
case Repo.get_by(Media,
id: arguments["mediaId"] || arguments["media_id"],
project_id: project_id
) do
%Media{} = media -> success_fun.(media)
nil -> not_found_result
end
end
defp maybe_put(map, _key, nil), do: map defp maybe_put(map, _key, nil), do: map
defp maybe_put(map, _key, ""), do: map defp maybe_put(map, _key, ""), do: map
defp maybe_put(map, key, value), do: Map.put(map, key, value) defp maybe_put(map, key, value), do: Map.put(map, key, value)