catentio

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 15, 2026 License: MIT Imports: 13 Imported by: 0

README

catentio-saas (Go)

Official Go SDK for the catentio-saas-go control plane. 1:1 parity with @forjio/catentio-saas-node and catentio_saas (Python) — same 25 resource namespaces, same Bearer auth via Huudis OIDC, same {data, error, meta} envelope.

Install

go get github.com/hachimi-cat/catentio-saas-go

Quickstart

Static API key (server-to-server)
package main

import (
    "context"
    "fmt"

    catentio "github.com/hachimi-cat/catentio-saas-go"
)

func main() {
    c := catentio.NewClient(catentio.ClientOptions{
        APIKey: "cat_pk_...",
    })
    raw, err := c.Workspaces.List(context.Background(), "")
    if err != nil { panic(err) }
    fmt.Println(string(raw))
}
Bearer session (CLI / device-flow)
import (
    catentio "github.com/hachimi-cat/catentio-saas-go"
    huudis "github.com/hachimi-cat/huudis-go"
)

// huudisClient performs the Huudis device-flow login elsewhere in your app.
session := catentio.NewSession(catentio.SessionOptions{
    AccessToken:  "...",
    RefreshToken: "...",
    ExpiresAt:    1_800_000_000,
    Issuer:       "https://huudis.com",
    ClientID:     "catentio-cli",
    // Single-flight refresh hook — wire huudis-go's RefreshAccessToken.
    RefreshFn: func(cur catentio.ProfileData) (catentio.ProfileData, error) {
        tok, err := huudisClient.RefreshAccessToken(context.Background(), cur.RefreshToken)
        if err != nil { return cur, err }
        return catentio.ProfileData{
            AccessToken:  tok.AccessToken,
            RefreshToken: tok.RefreshToken,
            ExpiresAt:    time.Now().Unix() + int64(tok.ExpiresIn),
            Issuer:       cur.Issuer,
            ClientID:     cur.ClientID,
            Scope:        tok.Scope,
        }, nil
    },
})

c := catentio.NewClient(catentio.ClientOptions{Session: session})
projects, err := c.Projects.List(context.Background(), "")

The Session keeps refresh single-flight so concurrent calls don't burn the Huudis refresh-token family (Huudis revokes the entire family on reuse).

Resource namespaces

Namespace Routes
c.Workspaces List, Show, Create, Destroy, SetState
c.Agents List, Get, Invoke
c.Runs List, Get, Cancel
c.Projects List, Get, Create, ListAttachments, AddAttachment, ListTasks, GetTask, ListSubtasks, GetSubtask, ListAttempts, ListArtifacts, ListEvents, Cost, Pause, Resume, Abandon, RunStep, RetrySubtask
c.Templates List
c.Tools List, Get, Create, Update, Delete
c.Skills List, Get
c.Memory Stats, ListEntries, GetEntry, CreateEntry, UpdateEntry
c.APIKeys List, Create, Delete
c.Billing Catalog, Summary, Subscribe
c.Cost Summary
c.Integrations List, Configure, Delete
c.Webhooks List, Create, Delete
c.ScheduledJobs List, Create, Update, Delete
c.FeatureFlags List, Set
c.Files List, Upload, Delete
c.OutputDestinations List, Get, Create, Update, Delete
c.Discord Status, SendMessage
c.Gojo Sessions
c.Heartbeats List, Config, UpdateConfig
c.System Info, Health (unauth)
c.Chat Send, History
c.Events List
c.InboundWebhooks List

Every method takes a trailing token string to override the client-level Bearer for a single call (pass "" to use the default). Methods return json.RawMessage plus an error — caller decides how to decode each route's specific payload.

Errors

import "errors"

_, err := c.Workspaces.Show(ctx, "ws_404", "")
var apiErr *catentio.Error
if errors.As(err, &apiErr) {
    fmt.Println(apiErr.Code, apiErr.Message, apiErr.Status, apiErr.RequestID)
}
var netErr *catentio.NetworkError
if errors.As(err, &netErr) {
    fmt.Println("transport failure:", netErr.Message)
}

Source

https://github.com/hachimi-cat/catentio-saas-go

License

MIT

Documentation

Overview

Package catentio is the official Go SDK for saas-catentio.

1:1 parity with @forjio/catentio-saas-node v0.1.0:

  • 25 resource namespaces wrapping every CP route module.
  • Bearer auth via the Huudis OIDC device flow (carry an access_token in a Session, or hand a static API key to the client constructor).
  • Forjio API envelope unwrap (`{data, error, meta}`) with `*Error` carrying status, request_id, and details.
  • Single-flight refresh hook (caller-supplied) so concurrent calls don't burn the Huudis refresh-token family.

Mirrors the Node + Python SDK shape. The Session is intentionally slim — there is no Go @forjio/sdk equivalent yet, so we inline the pattern same as the Python SDK does.

Client for Catentio's PUBLIC API — https://catent.io/v1/.

This is the surface you want if you are calling Catentio from your own code.

It is NOT the same thing as catentio.Client. That one speaks the internal control-plane protocol, which is authenticated by a browser session cookie and is not reachable with an API key — most of its methods cannot work from outside the portal. This file speaks the public API: nine endpoints, one credential.

cat, err := catentio.NewPublicClient("cat_pk_...")
if err != nil {
    return err
}
ref, err := cat.Runs.Create(ctx, catentio.CreateRunParams{
    Agent:   "fumi",
    Message: "Write me a headline.",
})
run, err := cat.Runs.Wait(ctx, ref.RunID, nil)
fmt.Println(run.Output)

Get a key from the Catentio portal under "API keys". It is shown once.

Scope, so there are no surprises: a key is bound to the workspace that created it. Runs and projects you create belong to that workspace, and a run id you do not own answers 404 rather than 403 — the API will not confirm that another tenant's object exists. The key reaches these nine endpoints and nothing else; it is not an admin credential.

Index

Constants

View Source
const DefaultBaseURL = "https://catentio.com"

DefaultBaseURL is the production saas-catentio control-plane root.

View Source
const DefaultPublicBaseURL = "https://catent.io"

DefaultPublicBaseURL is catent.io, NOT catentio.com — catentio.com 301s here, and a redirect on a POST is a good way to lose a body or a header depending on the client. Point at the real host.

Variables

View Source
var ErrRunTimeout = errors.New("catentio: run did not reach a terminal state in time")

ErrRunTimeout is returned by Runs.Wait when a run has not settled in time. The run itself keeps going — call Runs.Get again later.

View Source
var TerminalRunStates = []string{"succeeded", "failed", "cancelled", "error"}

TerminalRunStates are the states that stop a Wait. "succeeded" is the happy one; the others are terminal failures.

View Source
var WebhookEventTypes = []string{"run.succeeded", "run.failed", "project.completed"}

WebhookEventTypes is the closed set of webhook events. A typo is a 400 from the API, not a silent no-op — pass one of these, or "*" for all.

Functions

This section is empty.

Types

type APIError

type APIError struct {
	StatusCode int
	Detail     string
}

APIError is a non-2xx from the public API. Mirrors the Python SDK's CatentioAPIError. Use errors.As to reach it:

var apiErr *catentio.APIError
if errors.As(err, &apiErr) && apiErr.StatusCode == 404 { ... }

func (*APIError) Error

func (e *APIError) Error() string

type APIKeysResource

type APIKeysResource struct {
	// contains filtered or unexported fields
}

func (*APIKeysResource) Create

func (r *APIKeysResource) Create(ctx context.Context, input Body, token string) (json.RawMessage, error)

func (*APIKeysResource) Delete

func (r *APIKeysResource) Delete(ctx context.Context, id, token string) (json.RawMessage, error)

func (*APIKeysResource) List

func (r *APIKeysResource) List(ctx context.Context, token string) (json.RawMessage, error)

type AgentsResource

type AgentsResource struct {
	// contains filtered or unexported fields
}

func (*AgentsResource) Get

func (r *AgentsResource) Get(ctx context.Context, slug, token string) (json.RawMessage, error)

func (*AgentsResource) Invoke

func (r *AgentsResource) Invoke(ctx context.Context, slug string, input Body, token string) (json.RawMessage, error)

func (*AgentsResource) List

func (r *AgentsResource) List(ctx context.Context, token string) (json.RawMessage, error)

type ApiClient

type ApiClient struct {
	BaseURL          string
	Session          *Session
	HTTP             *http.Client
	RefreshBufferSec int64
	RetryOn5xx       int
	DefaultHeaders   map[string]string
}

ApiClient is the typed HTTP transport — Bearer auth, proactive + reactive refresh, envelope unwrap. Mirrors `@forjio/sdk`'s ApiClient and the Python SDK's ApiClient class.

func NewApiClient

func NewApiClient(opts ApiClientOptions) *ApiClient

NewApiClient builds an ApiClient with sensible defaults. BaseURL falls back to CATENTIO_BASE_URL or DefaultBaseURL.

func (*ApiClient) Delete

func (a *ApiClient) Delete(ctx context.Context, path string, opts *RequestOptions) (json.RawMessage, error)

Delete issues a DELETE request.

func (*ApiClient) Get

func (a *ApiClient) Get(ctx context.Context, path string, opts *RequestOptions) (json.RawMessage, error)

Get issues a GET request.

func (*ApiClient) Patch

func (a *ApiClient) Patch(ctx context.Context, path string, opts *RequestOptions) (json.RawMessage, error)

Patch issues a PATCH request.

func (*ApiClient) Post

func (a *ApiClient) Post(ctx context.Context, path string, opts *RequestOptions) (json.RawMessage, error)

Post issues a POST request.

func (*ApiClient) Put

func (a *ApiClient) Put(ctx context.Context, path string, opts *RequestOptions) (json.RawMessage, error)

Put issues a PUT request.

type ApiClientOptions

type ApiClientOptions struct {
	BaseURL          string
	Session          *Session
	HTTP             *http.Client
	RefreshBufferSec int64
	RetryOn5xx       int
	DefaultHeaders   map[string]string
}

ApiClientOptions configures NewApiClient.

type BillingResource

type BillingResource struct {
	// contains filtered or unexported fields
}

func (*BillingResource) Catalog

func (r *BillingResource) Catalog(ctx context.Context, token string) (json.RawMessage, error)

func (*BillingResource) Subscribe

func (r *BillingResource) Subscribe(ctx context.Context, input Body, token string) (json.RawMessage, error)

func (*BillingResource) Summary

func (r *BillingResource) Summary(ctx context.Context, token string) (json.RawMessage, error)

type Body

type Body = map[string]any

Body is the alias for arbitrary JSON request bodies — sugar so call sites don't have to spell out `map[string]any{...}` every time.

type ChatResource

type ChatResource struct {
	// contains filtered or unexported fields
}

func (*ChatResource) History

func (r *ChatResource) History(ctx context.Context, sessionID, token string) (json.RawMessage, error)

func (*ChatResource) Send

func (r *ChatResource) Send(ctx context.Context, input Body, token string) (json.RawMessage, error)

type Client

type Client struct {
	API    *ApiClient
	APIKey string

	Workspaces         *WorkspacesResource
	Agents             *AgentsResource
	Runs               *RunsResource
	Projects           *ProjectsResource
	Templates          *TemplatesResource
	Tools              *ToolsResource
	Skills             *SkillsResource
	Memory             *MemoryResource
	APIKeys            *APIKeysResource
	Billing            *BillingResource
	Cost               *CostResource
	Integrations       *IntegrationsResource
	Webhooks           *WebhooksResource
	ScheduledJobs      *ScheduledJobsResource
	FeatureFlags       *FeatureFlagsResource
	Files              *FilesResource
	OutputDestinations *OutputDestinationsResource
	Discord            *DiscordResource
	Gojo               *GojoResource
	Heartbeats         *HeartbeatsResource
	System             *SystemResource
	Chat               *ChatResource
	Events             *EventsResource
	InboundWebhooks    *InboundWebhooksResource
}

Client is the high-level SDK surface — instantiate once, hold for the lifetime of your process.

func NewClient

func NewClient(opts ClientOptions) *Client

NewClient builds a Client. Reads CATENTIO_BASE_URL + CATENTIO_API_KEY from env when ClientOptions leaves them empty.

type ClientOptions

type ClientOptions struct {
	// BaseURL — defaults to env `CATENTIO_BASE_URL`, then DefaultBaseURL.
	BaseURL string
	// Session — Bearer session with optional refresh hook. Mutually
	// orthogonal with APIKey: when both are set, APIKey wins per call.
	Session *Session
	// APIKey — static `cat_pk_...` key. Falls back to env `CATENTIO_API_KEY`.
	// NOTE: API keys are verified by the catentio RUNTIME, not by the control
	// plane — the CP only accepts the portal session header (and a Huudis JWT
	// on billing/chat/workspaces).
	APIKey string
	// HTTP — supply your own *http.Client for custom timeouts / transports.
	HTTP *http.Client
}

ClientOptions configures NewClient.

type CostResource

type CostResource struct {
	// contains filtered or unexported fields
}

func (*CostResource) Summary

func (r *CostResource) Summary(ctx context.Context, query Query, token string) (json.RawMessage, error)

type CreateProjectParams

type CreateProjectParams struct {
	TemplateSlug string
	Title        string
	Brief        string
	Params       map[string]any
	// CostBudgetUSD and TemplateVersion are pointers so that "unset" and "zero"
	// are distinguishable — a 0 budget is a real (if unhappy) value.
	CostBudgetUSD   *float64
	TemplateVersion *int
}

CreateProjectParams starts a pipeline project. Params must satisfy the template's declared spec — see Templates.List.

type CreateRunParams

type CreateRunParams struct {
	Agent    string
	Message  string
	ThreadID string
}

CreateRunParams dispatches an agent run. ThreadID is optional.

type CreateWebhookParams

type CreateWebhookParams struct {
	URL         string
	Events      []string
	Description string
}

CreateWebhookParams registers an endpoint. URL must be https:// — deliveries carry your run output. Events defaults to ["*"].

type DiscordResource

type DiscordResource struct {
	// contains filtered or unexported fields
}

func (*DiscordResource) SendMessage

func (r *DiscordResource) SendMessage(ctx context.Context, input Body, token string) (json.RawMessage, error)

func (*DiscordResource) Status

func (r *DiscordResource) Status(ctx context.Context, token string) (json.RawMessage, error)

type Error

type Error struct {
	Code      string
	Message   string
	Status    int
	RequestID string
	Details   map[string]any
}

Error is the typed error returned on Forjio API envelope failures (`{data: null, error: {...}, meta: {...}}`) and non-2xx HTTP responses from the saas-catentio control plane. Branch on `.Code` to react to specific failure modes.

Mirrors the Node + Python SDKs' `CatentioError`.

func (*Error) Error

func (e *Error) Error() string

type EventsResource

type EventsResource struct {
	// contains filtered or unexported fields
}

func (*EventsResource) List

func (r *EventsResource) List(ctx context.Context, query Query, token string) (json.RawMessage, error)

type FeatureFlagsResource

type FeatureFlagsResource struct {
	// contains filtered or unexported fields
}

func (*FeatureFlagsResource) List

func (*FeatureFlagsResource) Set

func (r *FeatureFlagsResource) Set(ctx context.Context, flag string, input Body, token string) (json.RawMessage, error)

type FilesResource

type FilesResource struct {
	// contains filtered or unexported fields
}

func (*FilesResource) Delete

func (r *FilesResource) Delete(ctx context.Context, id, token string) (json.RawMessage, error)

func (*FilesResource) List

func (r *FilesResource) List(ctx context.Context, query Query, token string) (json.RawMessage, error)

func (*FilesResource) Upload

func (r *FilesResource) Upload(ctx context.Context, input Body, token string) (json.RawMessage, error)

type GojoResource

type GojoResource struct {
	// contains filtered or unexported fields
}

func (*GojoResource) Sessions

func (r *GojoResource) Sessions(ctx context.Context, token string) (json.RawMessage, error)

type HeartbeatsResource

type HeartbeatsResource struct {
	// contains filtered or unexported fields
}

func (*HeartbeatsResource) Config

func (r *HeartbeatsResource) Config(ctx context.Context, token string) (json.RawMessage, error)

func (*HeartbeatsResource) List

func (r *HeartbeatsResource) List(ctx context.Context, token string) (json.RawMessage, error)

func (*HeartbeatsResource) UpdateConfig

func (r *HeartbeatsResource) UpdateConfig(ctx context.Context, patch Body, token string) (json.RawMessage, error)

type InboundWebhooksResource

type InboundWebhooksResource struct {
	// contains filtered or unexported fields
}

func (*InboundWebhooksResource) List

type IntegrationsResource

type IntegrationsResource struct {
	// contains filtered or unexported fields
}

func (*IntegrationsResource) Configure

func (r *IntegrationsResource) Configure(ctx context.Context, kind string, input Body, token string) (json.RawMessage, error)

func (*IntegrationsResource) Delete

func (r *IntegrationsResource) Delete(ctx context.Context, kind, token string) (json.RawMessage, error)

func (*IntegrationsResource) List

type MemoryResource

type MemoryResource struct {
	// contains filtered or unexported fields
}

func (*MemoryResource) CreateEntry

func (r *MemoryResource) CreateEntry(ctx context.Context, input Body, token string) (json.RawMessage, error)

func (*MemoryResource) GetEntry

func (r *MemoryResource) GetEntry(ctx context.Context, id, token string) (json.RawMessage, error)

func (*MemoryResource) ListEntries

func (r *MemoryResource) ListEntries(ctx context.Context, query Query, token string) (json.RawMessage, error)

func (*MemoryResource) Stats

func (r *MemoryResource) Stats(ctx context.Context, token string) (json.RawMessage, error)

func (*MemoryResource) UpdateEntry

func (r *MemoryResource) UpdateEntry(ctx context.Context, id string, patch Body, token string) (json.RawMessage, error)

type NetworkError

type NetworkError struct {
	Message string
}

NetworkError is returned on transport failures (DNS, connect refused, TLS, body read errors).

func (*NetworkError) Error

func (e *NetworkError) Error() string

type OutputDestinationsResource

type OutputDestinationsResource struct {
	// contains filtered or unexported fields
}

func (*OutputDestinationsResource) Create

func (r *OutputDestinationsResource) Create(ctx context.Context, input Body, token string) (json.RawMessage, error)

func (*OutputDestinationsResource) Delete

func (r *OutputDestinationsResource) Delete(ctx context.Context, id, token string) (json.RawMessage, error)

func (*OutputDestinationsResource) Get

func (*OutputDestinationsResource) List

func (*OutputDestinationsResource) Update

func (r *OutputDestinationsResource) Update(ctx context.Context, id string, patch Body, token string) (json.RawMessage, error)

type ProfileData

type ProfileData struct {
	AccessToken  string
	ExpiresAt    int64 // unix seconds; 0 = unknown/long-lived
	RefreshToken string
	Issuer       string
	ClientID     string
	Scope        string
}

ProfileData is the snapshot of an access-token profile carried by a Session. Mirrors @forjio/sdk's Profile shape and the Python SDK's ProfileData.

type Project

type Project = json.RawMessage

Project is returned as-is by the API; its shape depends on the template, so it stays raw rather than pretending to a schema it does not have.

type ProjectsResource

type ProjectsResource struct {
	// contains filtered or unexported fields
}

func (*ProjectsResource) Abandon

func (r *ProjectsResource) Abandon(ctx context.Context, id, token string) (json.RawMessage, error)

func (*ProjectsResource) AddAttachment

func (r *ProjectsResource) AddAttachment(ctx context.Context, id string, input Body, token string) (json.RawMessage, error)

func (*ProjectsResource) Cost

func (r *ProjectsResource) Cost(ctx context.Context, id, token string) (json.RawMessage, error)

func (*ProjectsResource) Create

func (r *ProjectsResource) Create(ctx context.Context, input Body, token string) (json.RawMessage, error)

func (*ProjectsResource) Get

func (r *ProjectsResource) Get(ctx context.Context, id, token string) (json.RawMessage, error)

func (*ProjectsResource) GetSubtask

func (r *ProjectsResource) GetSubtask(ctx context.Context, id, taskID, subtaskID, token string) (json.RawMessage, error)

func (*ProjectsResource) GetTask

func (r *ProjectsResource) GetTask(ctx context.Context, id, taskID, token string) (json.RawMessage, error)

func (*ProjectsResource) List

func (r *ProjectsResource) List(ctx context.Context, token string) (json.RawMessage, error)

func (*ProjectsResource) ListArtifacts

func (r *ProjectsResource) ListArtifacts(ctx context.Context, id, token string) (json.RawMessage, error)

func (*ProjectsResource) ListAttachments

func (r *ProjectsResource) ListAttachments(ctx context.Context, id, token string) (json.RawMessage, error)

func (*ProjectsResource) ListAttempts

func (r *ProjectsResource) ListAttempts(ctx context.Context, id, subtaskID, token string) (json.RawMessage, error)

func (*ProjectsResource) ListEvents

func (r *ProjectsResource) ListEvents(ctx context.Context, id, token string) (json.RawMessage, error)

func (*ProjectsResource) ListSubtasks

func (r *ProjectsResource) ListSubtasks(ctx context.Context, id, taskID, token string) (json.RawMessage, error)

func (*ProjectsResource) ListTasks

func (r *ProjectsResource) ListTasks(ctx context.Context, id, token string) (json.RawMessage, error)

func (*ProjectsResource) Pause

func (r *ProjectsResource) Pause(ctx context.Context, id, token string) (json.RawMessage, error)

func (*ProjectsResource) Resume

func (r *ProjectsResource) Resume(ctx context.Context, id, token string) (json.RawMessage, error)

func (*ProjectsResource) RetrySubtask

func (r *ProjectsResource) RetrySubtask(ctx context.Context, id, subtaskID, token string) (json.RawMessage, error)

func (*ProjectsResource) RunStep

func (r *ProjectsResource) RunStep(ctx context.Context, id string, input Body, token string) (json.RawMessage, error)

type PublicAgent

type PublicAgent struct {
	Slug        string `json:"slug"`
	Description string `json:"description"`
}

PublicAgent is an agent you can invoke. Trimmed on purpose — the prompt, the tool allowlist and the model pin are not echoed.

type PublicAgentsResource

type PublicAgentsResource struct {
	// contains filtered or unexported fields
}

func (*PublicAgentsResource) List

List returns the agents you can invoke: slug and description.

type PublicClient

type PublicClient struct {
	BaseURL    string
	HTTPClient *http.Client

	Agents    *PublicAgentsResource
	Templates *PublicTemplatesResource
	Runs      *PublicRunsResource
	Projects  *PublicProjectsResource
	Webhooks  *PublicWebhooksResource
	// contains filtered or unexported fields
}

PublicClient is the Catentio public API client. Safe for concurrent use.

func NewPublicClient

func NewPublicClient(apiKey string, opts ...PublicOption) (*PublicClient, error)

NewPublicClient builds a client for the public API. apiKey is your cat_pk_ key, from the portal under "API keys".

type PublicOption

type PublicOption func(*PublicClient)

PublicOption configures a PublicClient.

func WithPublicBaseURL

func WithPublicBaseURL(baseURL string) PublicOption

WithPublicBaseURL overrides the base URL. Only for testing against a non-production instance.

func WithPublicHTTPClient

func WithPublicHTTPClient(hc *http.Client) PublicOption

WithPublicHTTPClient supplies your own *http.Client (proxies, timeouts, test transports).

type PublicProjectsResource

type PublicProjectsResource struct {
	// contains filtered or unexported fields
}

func (*PublicProjectsResource) Create

Create starts a pipeline project from a template. Params must satisfy the template's declared spec — see Templates.List. A bad value comes back as a 400 with per-field errors, before anything runs.

func (*PublicProjectsResource) Get

func (r *PublicProjectsResource) Get(ctx context.Context, projectID string) (Project, error)

Get returns the status of a project you own.

type PublicRunsResource

type PublicRunsResource struct {
	// contains filtered or unexported fields
}

func (*PublicRunsResource) Create

Create dispatches an agent run.

func (*PublicRunsResource) Get

func (r *PublicRunsResource) Get(ctx context.Context, runID string) (*Run, error)

Get returns the status and output of a run you own.

func (*PublicRunsResource) Wait

func (r *PublicRunsResource) Wait(ctx context.Context, runID string, opts *WaitOptions) (*Run, error)

Wait polls until the run reaches a terminal state, then returns it.

Agent runs are asynchronous and routinely take tens of seconds, so polling is the normal path, not a workaround. Returns a *TimeoutError (matching errors.Is(err, ErrRunTimeout)) if the run has not settled within the timeout; the run itself keeps going — you can always call Get again later. A cancelled ctx aborts the wait and returns ctx.Err().

type PublicTemplate

type PublicTemplate struct {
	Slug        string          `json:"slug"`
	Version     int             `json:"version"`
	Description string          `json:"description"`
	Params      []TemplateParam `json:"params"`
}

PublicTemplate is a pipeline template a project can be started from.

type PublicTemplatesResource

type PublicTemplatesResource struct {
	// contains filtered or unexported fields
}

func (*PublicTemplatesResource) List

List returns the pipeline templates, each with the params it DECLARES as required. Read Params before calling Projects.Create — the API validates them and returns a 400 with per-field errors, so you get a real contract rather than a pipeline that misfires an hour in.

type PublicWebhooksResource

type PublicWebhooksResource struct {
	// contains filtered or unexported fields
}

func (*PublicWebhooksResource) Create

Create registers an endpoint. The signing Secret is returned ONCE — store it.

Events defaults to ["*"]. An unknown event type is a 400, not a silent no-op: a typo that matches nothing is a webhook that never fires and takes a day to diagnose.

Verify a delivery:

X-Catentio-Signature: t=<unix>,v1=<hex>
hex = HMAC-SHA256(secret, "<t>.<raw body>")

Reject a t older than a few minutes — that is what stops a replay.

func (*PublicWebhooksResource) Delete

func (r *PublicWebhooksResource) Delete(ctx context.Context, endpointID int) error

Delete removes an endpoint you own. Queued deliveries for it are dropped.

func (*PublicWebhooksResource) List

List returns your endpoints. The signing secret is NOT echoed back — it is shown once at creation, and listing it would turn any read into a credential leak.

type Query

type Query = map[string]any

Query is the alias for `?k=v` query maps. Values are stringified before being attached. nil values are dropped.

type RefreshError

type RefreshError struct {
	Code    string
	Message string
}

RefreshError is returned when refreshing an OIDC access token fails.

func (*RefreshError) Error

func (e *RefreshError) Error() string

type RefreshFn

type RefreshFn func(current ProfileData) (ProfileData, error)

RefreshFn is the caller-supplied callable that produces a refreshed ProfileData from the current one. Kept pluggable so the SDK doesn't take a hard dependency on the huudis-go device-flow module — wire your own (or `huudis.Client.RefreshAccessToken`) at construction.

type RequestOptions

type RequestOptions struct {
	Query     map[string]any
	Headers   map[string]string
	AuthToken string // per-call Bearer override; bypasses Session.
	Body      any    // marshalled as JSON if non-nil. Ignored for GET/DELETE.
}

RequestOptions tunes a single request. Pointer-receiver so callers can pass nil for "no overrides".

type Run

type Run struct {
	RunID       string `json:"run_id"`
	Status      string `json:"status"`
	Agent       string `json:"agent"`
	Output      string `json:"output"`
	Error       string `json:"error"`
	StartedAt   string `json:"started_at"`
	CompletedAt string `json:"completed_at"`
}

Run is the status and output of a run you own.

type RunRef

type RunRef struct {
	RunID  string `json:"run_id"`
	Status string `json:"status"`
}

RunRef is what Runs.Create hands back.

type RunsResource

type RunsResource struct {
	// contains filtered or unexported fields
}

func (*RunsResource) Cancel

func (r *RunsResource) Cancel(ctx context.Context, id, token string) (json.RawMessage, error)

func (*RunsResource) Get

func (r *RunsResource) Get(ctx context.Context, id, token string) (json.RawMessage, error)

func (*RunsResource) List

func (r *RunsResource) List(ctx context.Context, query Query, token string) (json.RawMessage, error)

type ScheduledJobsResource

type ScheduledJobsResource struct {
	// contains filtered or unexported fields
}

func (*ScheduledJobsResource) Create

func (r *ScheduledJobsResource) Create(ctx context.Context, input Body, token string) (json.RawMessage, error)

func (*ScheduledJobsResource) Delete

func (r *ScheduledJobsResource) Delete(ctx context.Context, id, token string) (json.RawMessage, error)

func (*ScheduledJobsResource) List

func (*ScheduledJobsResource) Update

func (r *ScheduledJobsResource) Update(ctx context.Context, id string, patch Body, token string) (json.RawMessage, error)

type Session

type Session struct {
	// contains filtered or unexported fields
}

Session is the in-memory Bearer session consumed by ApiClient. Pass a RefreshFn to enable proactive + reactive auto-refresh. Concurrent callers share a single in-flight refresh (single-flight) so the Huudis refresh-token family isn't burned by token reuse.

func NewSession

func NewSession(opts SessionOptions) *Session

NewSession constructs a Session. When AccessToken is empty the session is considered uninitialized — Data() returns nil and is_expired() returns true so the first request triggers a refresh (if a RefreshFn is wired in).

func (*Session) Data

func (s *Session) Data() *ProfileData

Data returns a snapshot of the current profile (or nil if none).

func (*Session) IsExpired

func (s *Session) IsExpired() bool

IsExpired reports whether the current token is expired (or absent).

func (*Session) Refresh

func (s *Session) Refresh() error

Refresh runs the wired RefreshFn under a single-flight lock so concurrent callers share one network roundtrip. Returns the RefreshFn's error verbatim if it fails. No-op when no RefreshFn was wired in (long-lived token mode).

func (*Session) SetData

func (s *Session) SetData(d ProfileData)

SetData replaces the current profile snapshot.

func (*Session) WillExpireSoon

func (s *Session) WillExpireSoon(bufferSec int64) bool

WillExpireSoon reports whether the token expires within bufferSec seconds. Empty/zero ExpiresAt is treated as long-lived (false).

type SessionOptions

type SessionOptions struct {
	AccessToken  string
	ExpiresAt    int64
	RefreshToken string
	Issuer       string
	ClientID     string
	Scope        string
	RefreshFn    RefreshFn
}

SessionOptions configures NewSession.

type SkillsResource

type SkillsResource struct {
	// contains filtered or unexported fields
}

func (*SkillsResource) Get

func (r *SkillsResource) Get(ctx context.Context, slug, token string) (json.RawMessage, error)

func (*SkillsResource) List

func (r *SkillsResource) List(ctx context.Context, token string) (json.RawMessage, error)

type SystemResource

type SystemResource struct {
	// contains filtered or unexported fields
}

func (*SystemResource) Health

func (r *SystemResource) Health(ctx context.Context) (json.RawMessage, error)

Health does not require auth — token is intentionally not threaded through. Mirrors the Node + Python SDK behaviour.

func (*SystemResource) Info

func (r *SystemResource) Info(ctx context.Context, token string) (json.RawMessage, error)

type TemplateParam

type TemplateParam struct {
	Key         string          `json:"key"`
	Type        string          `json:"type"`
	Label       string          `json:"label"`
	Description string          `json:"description"`
	Required    bool            `json:"required"`
	Default     json.RawMessage `json:"default"`
	Validation  json.RawMessage `json:"validation"`
	EnumValues  []any           `json:"enum_values"`
}

TemplateParam is one input a template DECLARES. Read these before creating a project — the API validates them and 400s with per-field errors.

type TemplatesResource

type TemplatesResource struct {
	// contains filtered or unexported fields
}

func (*TemplatesResource) List

func (r *TemplatesResource) List(ctx context.Context, token string) (json.RawMessage, error)

type TimeoutError

type TimeoutError struct {
	RunID      string
	LastStatus string
	Timeout    time.Duration
}

TimeoutError wraps ErrRunTimeout with the run it gave up on. errors.Is(err, catentio.ErrRunTimeout) matches it.

func (*TimeoutError) Error

func (e *TimeoutError) Error() string

func (*TimeoutError) Unwrap

func (e *TimeoutError) Unwrap() error

type ToolsResource

type ToolsResource struct {
	// contains filtered or unexported fields
}

func (*ToolsResource) Create

func (r *ToolsResource) Create(ctx context.Context, input Body, token string) (json.RawMessage, error)

func (*ToolsResource) Delete

func (r *ToolsResource) Delete(ctx context.Context, slug, token string) (json.RawMessage, error)

func (*ToolsResource) Get

func (r *ToolsResource) Get(ctx context.Context, slug, token string) (json.RawMessage, error)

func (*ToolsResource) List

func (r *ToolsResource) List(ctx context.Context, token string) (json.RawMessage, error)

func (*ToolsResource) Update

func (r *ToolsResource) Update(ctx context.Context, slug string, patch Body, token string) (json.RawMessage, error)

type WaitOptions

type WaitOptions struct {
	// Timeout defaults to 10 minutes.
	Timeout time.Duration
	// PollInterval defaults to 3s, same as the Python SDK.
	PollInterval time.Duration
}

WaitOptions tunes Runs.Wait. A nil *WaitOptions means the defaults.

type WebhookEndpoint

type WebhookEndpoint struct {
	ID          int      `json:"id"`
	URL         string   `json:"url"`
	Events      []string `json:"events"`
	Description string   `json:"description"`
	Active      bool     `json:"active"`
}

WebhookEndpoint is a registered delivery endpoint. The signing secret is NOT echoed on a list — it is shown once, at creation.

type WebhookEndpointCreated

type WebhookEndpointCreated struct {
	WebhookEndpoint
	Secret string `json:"secret"`
}

WebhookEndpointCreated additionally carries the signing Secret, returned ONCE.

type WebhooksResource

type WebhooksResource struct {
	// contains filtered or unexported fields
}

func (*WebhooksResource) Create

func (r *WebhooksResource) Create(ctx context.Context, input Body, token string) (json.RawMessage, error)

func (*WebhooksResource) Delete

func (r *WebhooksResource) Delete(ctx context.Context, id, token string) (json.RawMessage, error)

func (*WebhooksResource) List

func (r *WebhooksResource) List(ctx context.Context, token string) (json.RawMessage, error)

type WorkspacesResource

type WorkspacesResource struct {
	// contains filtered or unexported fields
}

func (*WorkspacesResource) Create

func (r *WorkspacesResource) Create(ctx context.Context, input Body, token string) (json.RawMessage, error)

func (*WorkspacesResource) Destroy

func (r *WorkspacesResource) Destroy(ctx context.Context, id, token string) (json.RawMessage, error)

func (*WorkspacesResource) List

func (r *WorkspacesResource) List(ctx context.Context, token string) (json.RawMessage, error)

func (*WorkspacesResource) SetState

func (r *WorkspacesResource) SetState(ctx context.Context, id string, input Body, token string) (json.RawMessage, error)

func (*WorkspacesResource) Show

func (r *WorkspacesResource) Show(ctx context.Context, id, token string) (json.RawMessage, error)

Jump to

Keyboard shortcuts

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