Class: Keycardai::A2A::ServiceDiscovery

Inherits:
Object
  • Object
show all
Defined in:
lib/keycardai/a2a/service_discovery.rb

Overview

Resolves an agent's base URL to its agent card, fetched from /.well-known/agent-card.json and cached (default 15 minutes, refreshable). A card must carry a name to be valid.

Constant Summary collapse

DEFAULT_CACHE_TTL =
900

Instance Method Summary collapse

Constructor Details

#initialize(http_client: OAuth::HTTP::NetHTTPClient.new, cache_ttl: DEFAULT_CACHE_TTL, timeout: nil, clock: -> { Time.now }) ⇒ ServiceDiscovery

Returns a new instance of ServiceDiscovery.

Parameters:

  • http_client (#get) (defaults to: OAuth::HTTP::NetHTTPClient.new)

    pluggable transport

  • cache_ttl (Numeric) (defaults to: DEFAULT_CACHE_TTL)

    card cache lifetime in seconds

  • timeout (Numeric, nil) (defaults to: nil)

    fetch timeout

  • clock (#call) (defaults to: -> { Time.now })

    returns the current Time; override in tests



17
18
19
20
21
22
23
24
25
# File 'lib/keycardai/a2a/service_discovery.rb', line 17

def initialize(http_client: OAuth::HTTP::NetHTTPClient.new, cache_ttl: DEFAULT_CACHE_TTL,
               timeout: nil, clock: -> { Time.now })
  @http_client = http_client
  @cache_ttl = cache_ttl
  @timeout = timeout
  @clock = clock
  @cards = {}
  @mutex = Mutex.new
end

Instance Method Details

#clear_cachevoid

This method returns an undefined value.

Drop all cached cards.



58
59
60
# File 'lib/keycardai/a2a/service_discovery.rb', line 58

def clear_cache
  @mutex.synchronize { @cards.clear }
end

#get_card(base_url) ⇒ Hash

The agent card for a base URL, served from cache while fresh.

Parameters:

  • base_url (String)

    the agent's base URL

Returns:

  • (Hash)

    the agent card

Raises:



32
33
34
35
36
37
38
39
40
41
# File 'lib/keycardai/a2a/service_discovery.rb', line 32

def get_card(base_url)
  key = base_url.chomp("/")
  cached = @mutex.synchronize do
    entry = @cards[key]
    entry[:card] if entry && @clock.call - entry[:fetched_at] <= @cache_ttl
  end
  return cached if cached

  refresh(key)
end

#refresh(base_url) ⇒ Hash

Fetch a fresh card, replacing any cached one.

Parameters:

  • base_url (String)

Returns:

  • (Hash)

Raises:



48
49
50
51
52
53
# File 'lib/keycardai/a2a/service_discovery.rb', line 48

def refresh(base_url)
  key = base_url.chomp("/")
  card = fetch_card(key)
  @mutex.synchronize { @cards[key] = { card: card, fetched_at: @clock.call } }
  card
end