discourse/plugins/discourse-ai/app/serializers/ai_custom_tool_serializer.rb
Sam 10d109e4c8
FEATURE: add credential bindings for AI tools (#37891)
Introduce a "secret contracts" system that lets AI tools
declare required credentials by alias and bind them to
existing AiSecret records via a new join table.

Key changes:
- New `ai_tool_secret_bindings` table and AiToolSecretBinding
  model linking AiTool to AiSecret by alias
- `secret_contracts` JSONB column on ai_tools for declaring
  required credential aliases
- `secrets.get(alias)` API available in tool scripts at
  runtime, with preloaded secret caching
- Admin UI for managing credential contracts and bindings on
  the tool editor form, with status badges on the tool list
- Tool presets (stock_quote, image generation) updated to use
  `secrets.get()` instead of hardcoded placeholder keys
- Secrets list editor shows tool usages alongside LLM and
  embedding usages
- Test modal supports passing secret bindings and rendering
  custom_raw output
- Validation, error handling, and i18n for contracts/bindings
- Persona import/export updated to include secret_contracts

---------

Co-authored-by: Keegan George <kgeorge13@gmail.com>
Co-authored-by: awesomerobot <kris.aubuchon@discourse.org>
2026-02-20 07:56:15 +11:00

37 lines
885 B
Ruby
Vendored

# frozen_string_literal: true
class AiCustomToolSerializer < ApplicationSerializer
attributes :id,
:name,
:tool_name,
:description,
:summary,
:parameters,
:script,
:secret_contracts,
:secret_bindings,
:rag_chunk_tokens,
:rag_chunk_overlap_tokens,
:rag_llm_model_id,
:created_by_id,
:created_at,
:updated_at
self.root = "ai_tool"
has_many :rag_uploads, serializer: UploadSerializer, embed: :object
def rag_uploads
object.uploads
end
def include_secret_bindings?
return true if scope.blank? || !scope.is_a?(Hash)
scope[:include_secret_bindings] != false
end
def secret_bindings
object.secret_bindings.map { |binding| binding.slice(:alias, :ai_secret_id) }
end
end