Extract card filtering
This commit is contained in:
@@ -2,6 +2,27 @@ class Ai::Tool < RubyLLM::Tool
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
private
|
||||
def paginated_response(records, page:, ordered_by:, per_page: nil, &block)
|
||||
page = GearedPagination::Recordset.new(records, ordered_by: ordered_by, per_page: per_page).page(page)
|
||||
|
||||
response = [ "There are #{page.recordset.records_count} records in total." ]
|
||||
|
||||
if page.only? || page.last?
|
||||
response << "This is the last page of results."
|
||||
else
|
||||
response << "This is one page of results."
|
||||
response << "To see more, use this cursor for the next page:"
|
||||
response << page.next_param
|
||||
end
|
||||
|
||||
response << "Records:"
|
||||
response << "```"
|
||||
response << page.records.map(&block).to_json
|
||||
response << "```"
|
||||
|
||||
response.join("\n")
|
||||
end
|
||||
|
||||
def default_url_options
|
||||
Rails.application.default_url_options
|
||||
.reverse_merge(host: "fizzy.localhost", port: 3006)
|
||||
|
||||
@@ -32,39 +32,39 @@ class Ai::Tool::ListCards < Ai::Tool
|
||||
- name [String, not null]
|
||||
MD
|
||||
|
||||
param :ids,
|
||||
param :page,
|
||||
type: :string,
|
||||
desc: "If provided, will return only the cards with the given IDs (comma-separated)",
|
||||
desc: "Which page to return. Leave balnk to get the first page",
|
||||
required: false
|
||||
param :query,
|
||||
type: :string,
|
||||
desc: "If provided, will perform a semantinc search by embeddings and return only matching cards",
|
||||
required: false
|
||||
param :page,
|
||||
param :ids,
|
||||
type: :string,
|
||||
desc: "Which page to return. Leave balnk to get the first page",
|
||||
desc: "If provided, will return only cards with the given IDs (comma-separated)",
|
||||
required: false
|
||||
param :collection_id,
|
||||
param :collection_ids,
|
||||
type: :integer,
|
||||
desc: "If provided, will return only cards for the specified collection",
|
||||
desc: "If provided, will return only cards for the specified collections (comma-separated)",
|
||||
required: false
|
||||
param :golden,
|
||||
type: :boolean,
|
||||
desc: "If provided, will return only golden cards",
|
||||
required: false
|
||||
param :created_at_gte,
|
||||
param :created_after,
|
||||
type: :string,
|
||||
desc: "If provided, will return only card created on or after after the given ISO timestamp",
|
||||
desc: "If provided, will return only cards created on or after the given ISO timestamp",
|
||||
required: false
|
||||
param :created_at_lte,
|
||||
param :created_before,
|
||||
type: :string,
|
||||
desc: "If provided, will return only card created on or before the given ISO timestamp",
|
||||
desc: "If provided, will return only cards created on or before the given ISO timestamp",
|
||||
required: false
|
||||
param :last_active_at_gte,
|
||||
param :last_active_after,
|
||||
type: :string,
|
||||
desc: "If provided, will return only card that were last active on or after after the given ISO timestamp",
|
||||
desc: "If provided, will return only card that were last active on or after the given ISO timestamp",
|
||||
required: false
|
||||
param :last_active_at_lte,
|
||||
param :last_active_before,
|
||||
type: :string,
|
||||
desc: "If provided, will return only card that were last active on or before the given ISO timestamp",
|
||||
required: false
|
||||
@@ -76,60 +76,33 @@ class Ai::Tool::ListCards < Ai::Tool
|
||||
end
|
||||
|
||||
def execute(**params)
|
||||
cards = Card.where(collection: user.collections).includes(:stage, :creator, :assignees, :goldness)
|
||||
cards = Card
|
||||
.where(collection: user.collections)
|
||||
.with_rich_text_description
|
||||
.includes(:stage, :creator, :assignees, :goldness, :collection)
|
||||
|
||||
cards = Filter.new(scope: cards, filters: params).filter
|
||||
cards = cards.search(params[:query]) if params[:query].present?
|
||||
cards = cards.golden if params[:golden].present?
|
||||
cards = cards.where(collection_id: params[:collection_id]) if params[:collection_id].present?
|
||||
cards = cards.where(id: params[:ids]&.split(",")&.map(&:to_i)) if params[:ids].present?
|
||||
|
||||
if params[:last_active_at_gte].present?
|
||||
timestamp = DateTime.parse(params[:last_active_at_gte])
|
||||
cards = cards.where(last_active_at: timestamp..)
|
||||
paginated_response(cards, page: params[:page], ordered_by: { created_at: :asc, id: :desc }) do |card|
|
||||
card_attributes(card)
|
||||
end
|
||||
|
||||
if params[:last_active_at_lte].present?
|
||||
timestamp = DateTime.parse(params[:last_active_at_lte])
|
||||
cards = cards.where(last_active_at: ..timestamp)
|
||||
end
|
||||
|
||||
if params[:created_at_gte].present?
|
||||
timestamp = DateTime.parse(params[:created_at_gte])
|
||||
cards = cards.where(created_at: timestamp..)
|
||||
end
|
||||
|
||||
if params[:created_at_lte].present?
|
||||
timestamp = DateTime.parse(params[:created_at_lte])
|
||||
cards = cards.where(created_at: ..timestamp)
|
||||
end
|
||||
|
||||
page = GearedPagination::Recordset.new(cards, ordered_by: { id: :desc }).page(params[:page])
|
||||
|
||||
puts "="*80
|
||||
puts "Account: #{Account.sole.id}"
|
||||
puts "Tenant: #{ApplicationRecord.current_tenant}"
|
||||
puts "URL options: #{default_url_options.inspect}"
|
||||
puts "="*80
|
||||
|
||||
{
|
||||
cards: page.records.map do |card|
|
||||
{
|
||||
id: card.id,
|
||||
title: card.title,
|
||||
status: card.status,
|
||||
last_active_at: card.last_active_at,
|
||||
collection_id: card.collection_id,
|
||||
golden: card.golden?,
|
||||
stage: card.stage.as_json(only: [ :id, :name ]),
|
||||
creator: card.creator.as_json(only: [ :id, :name ]),
|
||||
assignees: card.assignees.as_json(only: [ :id, :name ]),
|
||||
description: card.description.to_plain_text.truncate(1000),
|
||||
url: collection_card_url(card.collection, card)
|
||||
}
|
||||
end,
|
||||
pagination: {
|
||||
next_page: page.next_param
|
||||
}
|
||||
}.to_json
|
||||
end
|
||||
|
||||
private
|
||||
def card_attributes(card)
|
||||
{
|
||||
id: card.id,
|
||||
title: card.title,
|
||||
status: card.status,
|
||||
last_active_at: card.last_active_at,
|
||||
collection_id: card.collection_id,
|
||||
golden: card.golden?,
|
||||
stage: card.stage.as_json(only: [ :id, :name ]),
|
||||
creator: card.creator.as_json(only: [ :id, :name ]),
|
||||
assignees: card.assignees.as_json(only: [ :id, :name ]),
|
||||
description: card.description.to_plain_text.truncate(1000),
|
||||
url: collection_card_url(card.collection, card)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
class Ai::Tool::ListCards::Filter
|
||||
FILTERS = {
|
||||
ids: :apply_ids_filter,
|
||||
collection_ids: :apply_collection_ids_filter,
|
||||
golden: :apply_golden_filter,
|
||||
created_before: :apply_created_before_filter,
|
||||
created_after: :apply_created_after_filter,
|
||||
last_active_before: :apply_last_active_before_filter,
|
||||
last_active_after: :apply_last_active_after_filter
|
||||
}.freeze
|
||||
|
||||
attr_reader :scope, :filters
|
||||
|
||||
def initialize(scope:, filters:)
|
||||
@scope = scope
|
||||
@filters = filters
|
||||
end
|
||||
|
||||
def filter
|
||||
FILTERS.reduce(scope) do |filtered_scope, (filter_name, method_name)|
|
||||
if filters[filter_name].present?
|
||||
send(method_name, filtered_scope)
|
||||
else
|
||||
filtered_scope
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def apply_ids_filter(scope)
|
||||
scope.where(id: filters[:ids])
|
||||
end
|
||||
|
||||
def apply_collection_ids_filter(scope)
|
||||
scope.where(collection_id: filters[:collection_ids])
|
||||
end
|
||||
|
||||
def apply_golden_filter(scope)
|
||||
scope.golden
|
||||
end
|
||||
|
||||
def apply_created_before_filter(scope)
|
||||
scope.where(created_at: ...filters[:created_before])
|
||||
end
|
||||
|
||||
def apply_created_after_filter(scope)
|
||||
scope.where(created_at: filters[:created_after]...)
|
||||
end
|
||||
|
||||
def apply_last_active_before_filter(scope)
|
||||
scope.where(last_active_at: ...filters[:last_active_before])
|
||||
end
|
||||
|
||||
def apply_last_active_after_filter(scope)
|
||||
scope.where(last_active_at: filters[:last_active_after]...)
|
||||
end
|
||||
end
|
||||
@@ -68,7 +68,7 @@ class Ai::Tool::ListComments < Ai::Tool
|
||||
|
||||
def execute(**params)
|
||||
cards = Card.where(collection: user.collections)
|
||||
scope = Comment.where(card: cards).includes(:card, :creator, reactions: [ :reacter ])
|
||||
scope = Comment.where(card: cards).with_rich_text_description.includes(:card, :creator, reactions: [ :reacter ])
|
||||
|
||||
scope = scope.search(params[:query]) if params[:query].present?
|
||||
scope = scope.where(card_id: params[:card_id].to_i) if params[:card_id].present?
|
||||
|
||||
Reference in New Issue
Block a user