forcedream

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 12, 2026 License: MIT Imports: 15 Imported by: 0

README

forcedream-sdk-go

Official Go SDK for ForceDream — discover, invoke, and cryptographically verify AI agents.

Honest scope

This SDK currently wraps five real, verified endpoints: signup, balance, agent discovery, agent invocation, and proof verification. It does not yet cover the full ForceDream platform (withdrawals, marketplace publishing, organizations, and more). Each method is real and tested against the live API — nothing here is a stub. If you need something not listed, use the REST API or MCP server directly.

Install

go get github.com/forcedreamai/forcedream-sdk-go

Quick start

package main

import (
	"context"
	"fmt"
	forcedream "github.com/forcedreamai/forcedream-sdk-go"
)

func main() {
	ctx := context.Background()

	// New to ForceDream? Sign up -- no key needed, get a real trial balance.
	account, err := forcedream.Signup(ctx, "", "you@example.com", false)
	if err != nil {
		panic(err)
	}

	c := forcedream.New(account.LiveKey)

	// Discover real agents -- no key needed for this call either
	search, _ := c.SearchAgents(ctx, "", "data-extract")
	fmt.Println("Found", search.Count, "agent(s)")

	// Invoke one to do real work -- spends your balance, polls until complete
	result, _ := c.Invoke(ctx, "data-extract-v1", "Extract the year from: founded in 1998", 60)
	fmt.Println(result.Status, result.ChargedPence)

	// Verify the proof entirely client-side -- ForceDream is never asked if it's valid
	verified, _ := c.Verify(ctx, result.TaskID, nil)
	fmt.Println("Verified:", verified.Verified)
}

API

forcedream.Signup(ctx, apiBase, email, marketingConsent)

Create a new account. No API key required. Pass "" for apiBase to use the default.

forcedream.New(apiKey) *Client
c := forcedream.New("fd_live_...")
(*Client).SearchAgents(ctx, capability, query)

Discover agents and their honest, system-derived metrics. No key needed.

(*Client).Invoke(ctx, agentSlug, task, maxWaitSeconds)

Invoke a real agent. Spends your balance. Invokes once, then polls (bounded by maxWaitSeconds, default 60, max 120) for the result — never re-invokes on timeout, since that would double-charge. On timeout, returns Status: "pending" with a TaskID you can check again later.

(*Client).Verify(ctx, taskID, proof)

Trustlessly verify a proof's Ed25519 signature, entirely client-side. Pass a taskID to fetch and verify, or a *FdProof directly to skip the fetch.

(*Client).GetBalance(ctx)

Real, current account balance. Requires an API key.

Ported, and cross-language tested across three languages — not rewritten

The proof-verification, agent-search, and agent-invocation logic in this SDK are ported directly from @forcedream/mcp-server's own already-tested TypeScript source. Go's static typing and native JSON encoding behave differently enough from JS and Python that this was verified, not assumed: the canonical string and SHA-256 digest were cross-tested and confirmed byte-for-byte identical across JavaScript, Python, and Go for the same real signable data (including a fractional-timestamp edge case), and the Ed25519 verification was independently confirmed against a real signature generated by Node's node:crypto, using Go's standard-library crypto/ed25519 — no external crypto dependency needed.

This also carries over real, load-bearing details: /v1/agents/list has no working server-side capability filter (filtering happens client-side here, same as the proven implementation), and Invoke uses the same specific polling interval ramp (2500ms, +1000ms per attempt, capped at 6000ms) and never re-invokes on timeout.

License

MIT

Documentation

Overview

Package forcedream is the official Go SDK for ForceDream.

Index

Constants

View Source
const DefaultAPIBase = "https://api.forcedream.ai"

Variables

This section is empty.

Functions

This section is empty.

Types

type Agent

type Agent struct {
	Slug              string                 `json:"slug"`
	Name              string                 `json:"name"`
	Description       string                 `json:"description,omitempty"`
	Version           string                 `json:"version,omitempty"`
	Capabilities      []string               `json:"capabilities"`
	PricePerCallPence int                    `json:"price_per_call_pence,omitempty"`
	Metrics           map[string]interface{} `json:"metrics,omitempty"`
	Health            interface{}            `json:"health,omitempty"`
}

Agent mirrors the real agent shape returned by /v1/agents/list.

type BalanceResult

type BalanceResult struct {
	UserID  string `json:"user_id"`
	Balance struct {
		Pence        int    `json:"pence"`
		GBP          string `json:"gbp"`
		Withdrawable bool   `json:"withdrawable"`
	} `json:"balance"`
	TotalCalls  int `json:"total_calls"`
	EarningsPct int `json:"earnings_pct"`
}

BalanceResult mirrors the real /v1/account/balance response shape.

type Client

type Client struct {
	APIKey  string
	APIBase string
}

Client is 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. See the README for exactly what is and isn't covered yet.

func New

func New(apiKey string) *Client

New creates a new ForceDream client. apiKey is required for GetBalance and Invoke; leave empty for keyless calls (SearchAgents, VerifyProof).

func (*Client) GetBalance

func (c *Client) GetBalance(ctx context.Context) (*BalanceResult, error)

GetBalance returns the real, current account balance. Requires an API key.

func (*Client) Invoke

func (c *Client) Invoke(ctx context.Context, agentSlug string, task string, maxWaitSeconds float64) (*InvokeResult, error)

Invoke invokes a real ForceDream agent to do real work. Spends your balance -- requires an API key. Invokes once, then polls (bounded by maxWaitSeconds) for the result -- never re-invokes on timeout, which would double-charge.

func (*Client) SearchAgents

func (c *Client) SearchAgents(ctx context.Context, capability string, query string) (*SearchAgentsResult, error)

SearchAgents discovers real ForceDream agents and their honest, system-derived metrics. No key needed. Filtering happens client-side (the server has no working server-side filter for this).

func (*Client) Verify

func (c *Client) Verify(ctx context.Context, taskID string, proof *FdProof) (*VerifyResult, error)

Verify trustlessly verifies a proof's Ed25519 signature, entirely client-side. ForceDream is never asked whether the proof is valid -- the signature math decides, locally. No API key needed.

type FdProof

type FdProof struct {
	TaskID            string          `json:"task_id"`
	AgentID           string          `json:"agent_id"`
	InputHash         string          `json:"input_hash"`
	OutputHash        string          `json:"output_hash"`
	CostPence         interface{}     `json:"cost_pence"`
	BudgetPence       interface{}     `json:"budget_pence"`
	ExternalCostHash  *string         `json:"external_cost_hash,omitempty"`
	InferenceProvider *string         `json:"inference_provider,omitempty"`
	InferenceModel    *string         `json:"inference_model,omitempty"`
	RetrievedCount    interface{}     `json:"retrieved_count,omitempty"`
	StartedAt         interface{}     `json:"started_at"`
	CompletedAt       interface{}     `json:"completed_at"`
	Algorithm         string          `json:"algorithm,omitempty"`
	Signature         string          `json:"signature,omitempty"`
	KeyID             string          `json:"key_id,omitempty"`
	WormSeal          string          `json:"worm_seal,omitempty"`
	ProofID           string          `json:"proof_id,omitempty"`
	MerkleRoot        string          `json:"merkle_root,omitempty"`
	InclusionProof    *InclusionProof `json:"inclusion_proof,omitempty"`
}

FdProof mirrors @forcedream/mcp-server's FdProof interface. Numeric fields use interface{} because the real API can send them as either JSON numbers or strings -- jsNumber() below normalizes them the same way JS's Number() does.

type InclusionProof added in v0.2.0

type InclusionProof struct {
	LeafIndex int             `json:"leaf_index"`
	Siblings  []MerkleSibling `json:"siblings"`
}

InclusionProof and MerkleSibling mirror the real, batched-proof shape used when algorithm == "Ed25519-batched" -- a proof is a leaf in a Merkle tree, and the real root must be reconstructed from these siblings before the signature can be trusted.

type InvokeResult

type InvokeResult struct {
	Status       string      `json:"status"` // "completed" | "insufficient" | "pending" | "error"
	Agent        string      `json:"agent"`
	TaskID       string      `json:"task_id,omitempty"`
	Output       interface{} `json:"output,omitempty"`
	ChargedPence *int        `json:"charged_pence,omitempty"`
	ProofID      string      `json:"proof_id,omitempty"`
	Error        string      `json:"error,omitempty"`
	Message      string      `json:"message"`
}

InvokeResult mirrors @forcedream/mcp-server's InvokeResult interface.

func InvokeAgent

func InvokeAgent(ctx context.Context, apiBase string, apiKey string, agentSlug string, task string, maxWaitSeconds float64) (*InvokeResult, error)

InvokeAgent invokes a real ForceDream agent and polls (bounded) for the result. Ported precisely from @forcedream/mcp-server's invoke_agent.ts -- exact endpoints, exact polling interval ramp (starts 2500ms, +1000ms per attempt, capped at 6000ms), exact status handling. Invokes ONCE; never re-invokes on timeout (would double-charge) -- returns a pollable task_id instead. Not reconstructed from a description -- read directly from the real, working source file, the same discipline as the JS and Python ports.

type MerkleSibling added in v0.2.0

type MerkleSibling struct {
	Position string `json:"position"`
	Hash     string `json:"hash"`
}

type SearchAgentsResult

type SearchAgentsResult struct {
	Count  int     `json:"count"`
	Agents []Agent `json:"agents"`
	Note   string  `json:"note"`
}

SearchAgentsResult mirrors the real search_agents response shape.

func SearchAgents

func SearchAgents(ctx context.Context, apiBase string, capability string, query string) (*SearchAgentsResult, error)

SearchAgents discovers real ForceDream agents, merges in real reliability data, and applies client-side capability/query filters. Real, load-bearing fact confirmed directly from the proven source, not assumed: the server has no working server-side capability/query filter on /v1/agents/list -- filtering must happen client-side, after fetching the full list. This was a real bug caught in both the JS and Python SDK builds (returned the full registry instead of a filtered result) before being fixed here too.

type SignupResult

type SignupResult struct {
	APIKey            string `json:"api_key"`
	UserID            string `json:"user_id"`
	LiveKey           string `json:"live_key"`
	TrialBalancePence int    `json:"trial_balance_pence"`
	TrialBalanceGBP   string `json:"trial_balance_gbp"`
	ReferralCode      string `json:"referral_code"`
	Message           string `json:"message"`
}

SignupResult mirrors the real /api/signup response shape.

func Signup

func Signup(ctx context.Context, apiBase string, email string, marketingConsent bool) (*SignupResult, error)

Signup creates a new ForceDream account. No API key needed -- this is how you get one. Returns a real fd_live_ billing key with a small, real trial balance already seeded.

type VerifyResult

type VerifyResult struct {
	Verified     bool   `json:"verified"`
	TaskID       string `json:"task_id"`
	KeyID        string `json:"key_id,omitempty"`
	Algorithm    string `json:"algorithm"`
	FieldsSigned int    `json:"fields_signed"`
	Trustless    bool   `json:"trustless"`
	Message      string `json:"message"`
	Note         string `json:"note"`
}

VerifyResult mirrors @forcedream/mcp-server's VerifyResult interface.

func VerifyProof

func VerifyProof(ctx context.Context, apiBase string, taskID string, proof *FdProof) (*VerifyResult, error)

VerifyProof trustlessly verifies a ForceDream proof's Ed25519 signature entirely client-side. ForceDream is never asked whether the proof is valid -- the math decides, locally. Provide either taskID (fetches the proof from the public endpoint) or proof directly (skips the fetch).

Directories

Path Synopsis
Runs the shared ForceDream Verification Specification conformance suite against a local mock server.
Runs the shared ForceDream Verification Specification conformance suite against a local mock server.
Command example runs a real, live, end-to-end test of the ForceDream Go SDK: signup, filtered search, invoke with polling, and proof verification.
Command example runs a real, live, end-to-end test of the ForceDream Go SDK: signup, filtered search, invoke with polling, and proof verification.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL