Go SDK
The official Go SDK for Plasmate, with typed structs and SOM query functions.
Installation
go get github.com/nickel-org/plasmate-go
Requires Go 1.21+ and the plasmate binary on your PATH.
Quick Start
package main
import (
"fmt"
"log"
plasmate "github.com/nickel-org/plasmate-go"
)
func main() {
client := plasmate.NewClient()
defer client.Close()
som, err := client.FetchPage("https://example.com")
if err != nil {
log.Fatal(err)
}
fmt.Println(som.Title)
fmt.Printf("Regions: %d, Elements: %d\n", len(som.Regions), som.Meta.ElementCount)
}
Go Structs
`Som`
type Som struct {
SOMVersion string `json:"som_version"`
URL string `json:"url"`
Title string `json:"title"`
Lang string `json:"lang"`
Regions []Region `json:"regions"`
Meta SomMeta `json:"meta"`
StructuredData *StructuredData `json:"structured_data,omitempty"`
}
`Region`
type Region struct {
ID string `json:"id"`
Role string `json:"role"` // navigation, main, aside, header, footer, form, dialog, content
Label *string `json:"label,omitempty"`
Action *string `json:"action,omitempty"`
Method *string `json:"method,omitempty"`
Elements []Element `json:"elements"`
}
`Element`
type Element struct {
ID string `json:"id"`
Role string `json:"role"` // link, button, text_input, textarea, select, checkbox, radio, heading, image, list, table, paragraph, section, separator
Text *string `json:"text,omitempty"`
Label *string `json:"label,omitempty"`
Actions []string `json:"actions,omitempty"`
Attrs *ElementAttrs `json:"attrs,omitempty"`
Children []Element `json:"children,omitempty"`
Hints []string `json:"hints,omitempty"`
}
`SomMeta`
type SomMeta struct {
HTMLBytes int `json:"html_bytes"`
SOMBytes int `json:"som_bytes"`
ElementCount int `json:"element_count"`
InteractiveCount int `json:"interactive_count"`
}
Query Functions
`Parse(data)`
Parse raw JSON bytes into a Som struct.
som, err := plasmate.Parse(jsonBytes)
`FindByRole(som, role)`
Find all regions matching a given role.
navRegions := plasmate.FindByRole(som, "navigation")
`FindByID(som, id)`
Find a single element by its stable ID. Returns nil if not found.
el := plasmate.FindByID(som, "login-btn")
if el != nil {
fmt.Println(*el.Text)
}
`FindByTag(som, tag)`
Find elements matching a tag/role string.
links := plasmate.FindByTag(som, "link")
`FindInteractive(som)`
Return all interactive elements.
interactive := plasmate.FindInteractive(som)
fmt.Printf("%d interactive elements\n", len(interactive))
`GetActionPlanIndex(som, enabledOnly...)`
Return compact action targets indexed by replay ids and grouped by role/action. Use this before prompt construction or replay validation when you only need a menu of enabled buttons, links, inputs, or one action type.
index := plasmate.GetActionPlanIndex(som, true)
buttons := index.ByRole["button"]
clickTargets := index.ByAction["click"]
planSelect := index.ByLabel["Plan"]
`FindActionTargetsByRole(som, role, enabledOnly...)`
Return compact action targets for one SOM role without scanning the full plan.
buttons := plasmate.FindActionTargetsByRole(som, "button", true)
`FindActionTargetsByAction(som, action, enabledOnly...)`
Return compact action targets exposing one action.
clicks := plasmate.FindActionTargetsByAction(som, "click", true)
`FindActionTargetByLabel(som, label)`
Resolve the first compact action target with an exact accessible label. Treat labels as human-facing recovery hints; store SOM ids, cache keys, HTML ids, or test ids for unattended replay.
target := plasmate.FindActionTargetByLabel(som, "Plan")
`FindByText(som, text)`
Find elements whose text content contains the given string (case-insensitive).
matches := plasmate.FindByText(som, "Sign in")
`FlatElements(som)`
Flatten all elements across all regions into a single slice.
all := plasmate.FlatElements(som)
`TokenEstimate(som)`
Estimate the LLM token count for the SOM (heuristic: SOMBytes / 4).
tokens := plasmate.TokenEstimate(som)
fmt.Printf("~%d tokens\n", tokens)
Client Usage
Creating a Client
// Default options
client := plasmate.NewClient()
// Custom binary path
client := plasmate.NewClient(plasmate.WithBinary("/usr/local/bin/plasmate"))
Stateless Methods
// Fetch a page and return SOM
som, err := client.FetchPage("https://example.com")
// Fetch with options
som, err := client.FetchPageWithOptions("https://example.com", plasmate.FetchOptions{
Budget: 8000,
JavaScript: true,
})
// Extract plain text
text, err := client.ExtractText("https://example.com")
Stateful Sessions
// Open a persistent page session
session, err := client.OpenPage("https://example.com")
// session.SessionID, session.Som
// Execute JavaScript
result, err := client.Evaluate(session.SessionID, "document.title")
// Click an element and get updated SOM
updatedSom, err := client.Click(session.SessionID, "login-btn")
// Close the session
err = client.ClosePage(session.SessionID)
Cleanup
err := client.Close()
The client is thread-safe with internal mutex protection. It communicates with the plasmate mcp subprocess over JSON-RPC 2.0 on stdio.