Class: Assistant::AdlabsToolBuilder
- Inherits:
-
Object
- Object
- Assistant::AdlabsToolBuilder
- Defined in:
- app/services/assistant/adlabs_tool_builder.rb
Overview
Builds RubyLLM tools for the AdLabs (Amazon Ads / PPC) MCP server so the
assistant (Sunny) can drive AdLabs's stateful, reference-based workflow.
Unlike the curated one-shot builders (e.g. AhrefsToolBuilder), AdLabs is a
full conversational MCP surface, so tools are discovered dynamically and
exposed with their upstream names and JSON schemas passed straight through to
the LLM. Keeping the upstream names is deliberate: AdLabs ships its own
operating instructions (read at runtime via
+read_resource(uri: 'adlabs://instructions')+) and its tool descriptions
cross-reference each other by name, so renaming would break that coherence.
A single Marketing::AdlabsMcpClient instance backs every tool in one build
so the +chat_session_id+ and +mcp://data/...+ references resolve within a
turn. The catalog (tool names + schemas) is cached app-wide; only the
execution client is per-build.
Read vs. write is role-gated. The mutating tools — which change bids,
targets, tags, and jobs on the live Amazon Ads account — are built only for
accounts with the +amazon_ad_specialist+ role (or admins). Everyone else who
has the +adlabs+ service gets the read-only subset. The mixed-action tools
(+optimizer+, +tags+, +logs+) are held whole to the specialist role because a
single +*_action+ argument flips them between reading and writing.
Constant Summary collapse
- WRITE_TOOLS =
Tools excluded from the read-only set (they can mutate the live ad account
or revert applied jobs). See class docs for why the mixed-action tools are
included here rather than action-gated. %w[create_entities update_entities optimizer tags logs].freeze
Class Method Summary collapse
-
.tools(account: nil, write: nil) ⇒ Array<RubyLLM::Tool>
Instantiated tools (empty on any failure).
-
.write_access?(account) ⇒ Boolean
True when +account+ may use the mutating AdLabs tools.
Class Method Details
.tools(account: nil, write: nil) ⇒ Array<RubyLLM::Tool>
Returns instantiated tools (empty on any failure).
37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'app/services/assistant/adlabs_tool_builder.rb', line 37 def tools(account: nil, write: nil) write = write_access?(account) if write.nil? catalog = Marketing::AdlabsMcpClient.catalog return [] if catalog.blank? client = Marketing::AdlabsMcpClient.new catalog = catalog.reject { |t| WRITE_TOOLS.include?(t['name']) } unless write catalog.map { |t| build_tool(t, client) } rescue StandardError => e Rails.logger.warn("[AdlabsToolBuilder] Failed to build AdLabs tools: #{e.}") [] end |
.write_access?(account) ⇒ Boolean
True when +account+ may use the mutating AdLabs tools.
53 54 55 56 57 |
# File 'app/services/assistant/adlabs_tool_builder.rb', line 53 def write_access?(account) return false unless account account.is_admin? || account.has_role?('amazon_ad_specialist', admin_check: false) end |