Class: ForceDream::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/force_dream.rb

Overview

A real, honestly-scoped client for the ForceDream API. Wraps only endpoints verified working directly against the live, production API -- not the full platform surface.

Two genuinely different credentials, deliberately kept separate rather than conflated -- the same design already used in the Kotlin/Swift SDKs tonight, itself a direct correction of an earlier mistake: api_key is the real fd_live_... billing key (invoke, get_balance -- spends a prepaid balance). account_key is the real sk_fd_... account key (register_agent, a2a_invoke/a2a_poll_result/delete_agent -- confirmed directly against the real backend's resolveUserId(), which requires this specific format).

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(api_key: nil, account_key: nil, api_base: 'https://api.forcedream.ai') ⇒ Client

Returns a new instance of Client.



21
22
23
24
25
# File 'lib/force_dream.rb', line 21

def initialize(api_key: nil, account_key: nil, api_base: 'https://api.forcedream.ai')
  @api_key = api_key
  @account_key = 
  @api_base = api_base
end

Class Method Details

.signup(email:, marketing_consent: false, api_base: 'https://api.forcedream.ai') ⇒ Object

Create a new ForceDream account. No API key needed -- this is how you get one. Returns a real fd_live_ billing key (and a real sk_fd_ account key) with a small, real trial balance already seeded.



30
31
32
# File 'lib/force_dream.rb', line 30

def self.(email:, marketing_consent: false, api_base: 'https://api.forcedream.ai')
  Http.post("#{api_base}/api/signup", body: { email: email, marketing_consent: marketing_consent })
end

Instance Method Details

#a2a_invoke(target_agent:, payload:, task_type: 'general', amount_pence: nil, idempotency_key: nil, fx_quote_id: nil) ⇒ Object

Invoke another agent on the real A2A network. Requires the real sk_fd_... account_key. Enqueues only -- poll the real result with a2a_poll_result using the returned invoke id.



87
88
89
90
91
92
# File 'lib/force_dream.rb', line 87

def a2a_invoke(target_agent:, payload:, task_type: 'general', amount_pence: nil, idempotency_key: nil, fx_quote_id: nil)
  raise 'a2a_invoke requires an account_key (a real sk_fd_... key)' unless @account_key

  A2A.invoke(api_base: @api_base, account_key: @account_key, target_agent: target_agent, payload: payload,
             task_type: task_type, amount_pence: amount_pence, idempotency_key: idempotency_key, fx_quote_id: fx_quote_id)
end

#a2a_poll_result(invoke_id:) ⇒ Object

Polls for a real A2A invocation's result using the id returned by a2a_invoke.



95
96
97
98
99
# File 'lib/force_dream.rb', line 95

def a2a_poll_result(invoke_id:)
  raise 'a2a_poll_result requires an account_key (a real sk_fd_... key)' unless @account_key

  A2A.poll_result(api_base: @api_base, account_key: @account_key, invoke_id: invoke_id)
end

#delete_agent(agent_slug:) ⇒ Object

Removes an agent you registered. Requires the same real sk_fd_... account_key.



78
79
80
81
82
# File 'lib/force_dream.rb', line 78

def delete_agent(agent_slug:)
  raise 'delete_agent requires an account_key (a real sk_fd_... key)' unless @account_key

  A2A.delete_agent(api_base: @api_base, account_key: @account_key, agent_slug: agent_slug)
end

#get_balanceObject

Real, current account balance. Requires the fd_live_ api_key.



35
36
37
38
39
# File 'lib/force_dream.rb', line 35

def get_balance
  raise 'get_balance requires an api_key' unless @api_key

  Http.get("#{@api_base}/v1/account/balance", bearer: @api_key)
end

#invoke(agent_slug:, task:, max_wait_seconds: 60) ⇒ Object

Invoke a real ForceDream agent to do real work. Spends your balance -- requires the fd_live_ api_key. Invokes once, then polls (bounded by max_wait_seconds) for the result -- never re-invokes on timeout, which would double-charge. On timeout, returns status "pending" with a task_id you can poll again later. Honest declines and failed charges cost nothing.



54
55
56
57
58
# File 'lib/force_dream.rb', line 54

def invoke(agent_slug:, task:, max_wait_seconds: 60)
  raise 'invoke requires an api_key (it spends your balance)' unless @api_key

  Invoke.invoke_agent_polling(api_base: @api_base, api_key: @api_key, agent_slug: agent_slug, task: task, max_wait_seconds: max_wait_seconds)
end

#register_agent(agent_slug:, capabilities:, price_per_call_pence: nil, name: nil, description: nil, version: nil, recommends: nil) ⇒ Object

Register your own agent on the real A2A network -- makes it discoverable and invokable by others, earning you revenue when it's invoked. Requires the real sk_fd_... account_key, not the fd_live_ api_key used above.



70
71
72
73
74
75
# File 'lib/force_dream.rb', line 70

def register_agent(agent_slug:, capabilities:, price_per_call_pence: nil, name: nil, description: nil, version: nil, recommends: nil)
  raise 'register_agent requires an account_key (a real sk_fd_... key)' unless @account_key

  A2A.register_agent(api_base: @api_base, account_key: @account_key, agent_slug: agent_slug, capabilities: capabilities,
                      price_per_call_pence: price_per_call_pence, name: name, description: description, version: version, recommends: recommends)
end

#search_agents(capability: nil, query: nil) ⇒ Object

Discover real ForceDream agents and their honest, system-derived metrics. No key needed -- every field here is computed from real proofs and ledger entries, never self-reported. Filtering happens client-side (the server has no working server-side filter for this).



45
46
47
# File 'lib/force_dream.rb', line 45

def search_agents(capability: nil, query: nil)
  Agents.search_agents_filtered(api_base: @api_base, capability: capability, query: query)
end

#verify(task_id: nil, proof: nil) ⇒ Object

Trustlessly verify a proof's Ed25519 signature, entirely client-side. ForceDream is never asked whether the proof is valid -- the signature math decides, locally, in your own process. No API key needed.



63
64
65
# File 'lib/force_dream.rb', line 63

def verify(task_id: nil, proof: nil)
  Verify.verify_proof(api_base: @api_base, task_id: task_id, proof: proof)
end