From 1f70e735bad95b73c3eb89535479eac45f1c6dc3 Mon Sep 17 00:00:00 2001 From: "kernel-internal[bot]" <260533166+kernel-internal[bot]@users.noreply.github.com> Date: Thu, 13 Aug 2026 20:47:57 +0000 Subject: [PATCH 1/4] feat: Require a name on credential providers and backfill unnamed rows Stainless-Generated-From: d8057f2928875212b8a37f02ab023978e471f4d5 --- credentialprovider.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/credentialprovider.go b/credentialprovider.go index 77318a2..a05402e 100644 --- a/credentialprovider.go +++ b/credentialprovider.go @@ -142,7 +142,8 @@ func (r *CredentialProviderService) Test(ctx context.Context, id string, opts .. type CreateCredentialProviderRequestParam struct { // Service account token for the provider (e.g., 1Password service account token) Token string `json:"token" api:"required"` - // Human-readable name for this provider instance (unique per org) + // Human-readable name for this provider instance (unique per org). Surrounding + // whitespace is trimmed and the trimmed value must be non-empty. Name string `json:"name" api:"required"` // Type of credential provider // @@ -299,7 +300,8 @@ type UpdateCredentialProviderRequestParam struct { CacheTtlSeconds param.Opt[int64] `json:"cache_ttl_seconds,omitzero"` // Whether the provider is enabled for credential lookups Enabled param.Opt[bool] `json:"enabled,omitzero"` - // Human-readable name for this provider instance + // Human-readable name for this provider instance. Surrounding whitespace is + // trimmed and the trimmed value must be non-empty. Name param.Opt[string] `json:"name,omitzero"` // Priority order for credential lookups (lower numbers are checked first) Priority param.Opt[int64] `json:"priority,omitzero"` From cb90eb77d34aaeb9302fb701a6a613d1f3ff51af Mon Sep 17 00:00:00 2001 From: "kernel-internal[bot]" <260533166+kernel-internal[bot]@users.noreply.github.com> Date: Fri, 14 Aug 2026 17:49:27 +0000 Subject: [PATCH 2/4] feat: Expose configurable browser memory Stainless-Generated-From: e760ec2201481e0ea5b785b9def0aa474334eb9f --- api.md | 2 ++ browser.go | 43 +++++++++++++++++++++++++++++++++++++++++++ browser_test.go | 1 + browserpool.go | 5 +++++ invocation.go | 5 +++++ 5 files changed, 56 insertions(+) diff --git a/api.md b/api.md index 60e3df2..51e8d56 100644 --- a/api.md +++ b/api.md @@ -69,6 +69,7 @@ Methods: Params Types: +- kernel.BrowserMemoryRequest - kernel.BrowserNetworkConfigParam - kernel.BrowserProxyConfigParam - kernel.BrowserProxyMode @@ -76,6 +77,7 @@ Params Types: Response Types: +- kernel.BrowserMemory - kernel.BrowserNetworkConfig - kernel.BrowserPoolRef - kernel.BrowserProxy diff --git a/browser.go b/browser.go index c65dc51..b72629f 100644 --- a/browser.go +++ b/browser.go @@ -166,6 +166,25 @@ func (r *BrowserService) LoadExtensions(ctx context.Context, id string, body Bro return err } +// Memory allocated to the browser session. +type BrowserMemory string + +const ( + BrowserMemory1GiB BrowserMemory = "1GiB" + BrowserMemory2GiB BrowserMemory = "2GiB" + BrowserMemory6GiB BrowserMemory = "6GiB" + BrowserMemory8GiB BrowserMemory = "8GiB" + BrowserMemory16GiB BrowserMemory = "16GiB" +) + +// Memory requested for a headful, non-GPU browser session. +type BrowserMemoryRequest string + +const ( + BrowserMemoryRequest8GiB BrowserMemoryRequest = "8GiB" + BrowserMemoryRequest16GiB BrowserMemoryRequest = "16GiB" +) + // Network configuration for a browser session or browser pool. type BrowserNetworkConfig struct { // Destinations the browser reaches directly through the session's own network @@ -453,6 +472,10 @@ type BrowserNewResponse struct { CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"` // Whether the browser session is running in headless mode. Headless bool `json:"headless" api:"required"` + // Memory allocated to the browser session. + // + // Any of "1GiB", "2GiB", "6GiB", "8GiB", "16GiB". + Memory BrowserMemory `json:"memory" api:"required"` // Geographic region of the browser session. Fixed once the session is created. // // Any of "us-east", "eu-west". @@ -531,6 +554,7 @@ type BrowserNewResponse struct { CdpWsURL respjson.Field CreatedAt respjson.Field Headless respjson.Field + Memory respjson.Field Region respjson.Field SessionID respjson.Field Stealth respjson.Field @@ -580,6 +604,10 @@ type BrowserGetResponse struct { CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"` // Whether the browser session is running in headless mode. Headless bool `json:"headless" api:"required"` + // Memory allocated to the browser session. + // + // Any of "1GiB", "2GiB", "6GiB", "8GiB", "16GiB". + Memory BrowserMemory `json:"memory" api:"required"` // Geographic region of the browser session. Fixed once the session is created. // // Any of "us-east", "eu-west". @@ -658,6 +686,7 @@ type BrowserGetResponse struct { CdpWsURL respjson.Field CreatedAt respjson.Field Headless respjson.Field + Memory respjson.Field Region respjson.Field SessionID respjson.Field Stealth respjson.Field @@ -707,6 +736,10 @@ type BrowserUpdateResponse struct { CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"` // Whether the browser session is running in headless mode. Headless bool `json:"headless" api:"required"` + // Memory allocated to the browser session. + // + // Any of "1GiB", "2GiB", "6GiB", "8GiB", "16GiB". + Memory BrowserMemory `json:"memory" api:"required"` // Geographic region of the browser session. Fixed once the session is created. // // Any of "us-east", "eu-west". @@ -785,6 +818,7 @@ type BrowserUpdateResponse struct { CdpWsURL respjson.Field CreatedAt respjson.Field Headless respjson.Field + Memory respjson.Field Region respjson.Field SessionID respjson.Field Stealth respjson.Field @@ -834,6 +868,10 @@ type BrowserListResponse struct { CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"` // Whether the browser session is running in headless mode. Headless bool `json:"headless" api:"required"` + // Memory allocated to the browser session. + // + // Any of "1GiB", "2GiB", "6GiB", "8GiB", "16GiB". + Memory BrowserMemory `json:"memory" api:"required"` // Geographic region of the browser session. Fixed once the session is created. // // Any of "us-east", "eu-west". @@ -912,6 +950,7 @@ type BrowserListResponse struct { CdpWsURL respjson.Field CreatedAt respjson.Field Headless respjson.Field + Memory respjson.Field Region respjson.Field SessionID respjson.Field Stealth respjson.Field @@ -1029,6 +1068,10 @@ type BrowserNewParams struct { ChromePolicy map[string]any `json:"chrome_policy,omitzero"` // List of browser extensions to load into the session. Provide each by id or name. Extensions []shared.BrowserExtensionParam `json:"extensions,omitzero"` + // Memory for a headful, non-GPU browser session. Defaults to 8GiB. + // + // Any of "8GiB", "16GiB". + Memory BrowserMemoryRequest `json:"memory,omitzero"` // Network configuration for the browser session. Cannot be changed after creation. Network BrowserNetworkConfigParam `json:"network,omitzero"` // Profile selection for the browser session. Provide either id or name. If diff --git a/browser_test.go b/browser_test.go index 552f46a..5fa2207 100644 --- a/browser_test.go +++ b/browser_test.go @@ -41,6 +41,7 @@ func TestBrowserNewWithOptionalParams(t *testing.T) { Headless: kernel.Bool(false), InvocationID: kernel.String("rr33xuugxj9h0bkf1rdt2bet"), KioskMode: kernel.Bool(true), + Memory: kernel.BrowserMemoryRequest8GiB, Name: kernel.String("checkout-flow-1"), Network: kernel.BrowserNetworkConfigParam{ PrivateHosts: []string{"*.example.ts.net", "100.64.0.0/10"}, diff --git a/browserpool.go b/browserpool.go index db1b640..fe6b483 100644 --- a/browserpool.go +++ b/browserpool.go @@ -347,6 +347,10 @@ type BrowserPoolAcquireResponse struct { CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"` // Whether the browser session is running in headless mode. Headless bool `json:"headless" api:"required"` + // Memory allocated to the browser session. + // + // Any of "1GiB", "2GiB", "6GiB", "8GiB", "16GiB". + Memory BrowserMemory `json:"memory" api:"required"` // Geographic region of the browser session. Fixed once the session is created. // // Any of "us-east", "eu-west". @@ -425,6 +429,7 @@ type BrowserPoolAcquireResponse struct { CdpWsURL respjson.Field CreatedAt respjson.Field Headless respjson.Field + Memory respjson.Field Region respjson.Field SessionID respjson.Field Stealth respjson.Field diff --git a/invocation.go b/invocation.go index f6a8433..f8eeb12 100644 --- a/invocation.go +++ b/invocation.go @@ -544,6 +544,10 @@ type InvocationListBrowsersResponseBrowser struct { CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"` // Whether the browser session is running in headless mode. Headless bool `json:"headless" api:"required"` + // Memory allocated to the browser session. + // + // Any of "1GiB", "2GiB", "6GiB", "8GiB", "16GiB". + Memory BrowserMemory `json:"memory" api:"required"` // Geographic region of the browser session. Fixed once the session is created. // // Any of "us-east", "eu-west". @@ -622,6 +626,7 @@ type InvocationListBrowsersResponseBrowser struct { CdpWsURL respjson.Field CreatedAt respjson.Field Headless respjson.Field + Memory respjson.Field Region respjson.Field SessionID respjson.Field Stealth respjson.Field From 25f9b283b2ec49a85a973bc267a6bde4c3872a76 Mon Sep 17 00:00:00 2001 From: "kernel-internal[bot]" <260533166+kernel-internal[bot]@users.noreply.github.com> Date: Fri, 14 Aug 2026 18:07:59 +0000 Subject: [PATCH 3/4] feat: Add customer-facing OTLP destination CRUD API Stainless-Generated-From: 8e08b8b3680bc87c55f7d227162b7e3a9ae39dd2 --- .stats.yml | 2 +- api.md | 16 +++ browser.go | 3 +- browsertelemetry.go | 3 +- client.go | 6 +- telemetry.go | 30 +++++ telemetrydestination.go | 241 +++++++++++++++++++++++++++++++++++ telemetrydestination_test.go | 152 ++++++++++++++++++++++ 8 files changed, 448 insertions(+), 5 deletions(-) create mode 100644 telemetry.go create mode 100644 telemetrydestination.go create mode 100644 telemetrydestination_test.go diff --git a/.stats.yml b/.stats.yml index 50996d4..98f97da 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1 +1 @@ -configured_endpoints: 134 +configured_endpoints: 139 diff --git a/api.md b/api.md index 51e8d56..5486d5f 100644 --- a/api.md +++ b/api.md @@ -322,6 +322,22 @@ Methods: - client.Auth.Connections.Submit(ctx context.Context, id string, body kernel.AuthConnectionSubmitParams) (\*kernel.SubmitFieldsResponse, error) - client.Auth.Connections.Timeline(ctx context.Context, id string, query kernel.AuthConnectionTimelineParams) (\*pagination.OffsetPagination[kernel.ManagedAuthTimelineEvent], error) +# Telemetry + +## Destinations + +Response Types: + +- kernel.OtlpDestination + +Methods: + +- client.Telemetry.Destinations.New(ctx context.Context, body kernel.TelemetryDestinationNewParams) (\*kernel.OtlpDestination, error) +- client.Telemetry.Destinations.Get(ctx context.Context, idOrName string) (\*kernel.OtlpDestination, error) +- client.Telemetry.Destinations.Update(ctx context.Context, idOrName string, body kernel.TelemetryDestinationUpdateParams) (\*kernel.OtlpDestination, error) +- client.Telemetry.Destinations.List(ctx context.Context, query kernel.TelemetryDestinationListParams) (\*pagination.OffsetPagination[kernel.OtlpDestination], error) +- client.Telemetry.Destinations.Delete(ctx context.Context, idOrName string) error + # Proxies Response Types: diff --git a/browser.go b/browser.go index b72629f..bb9c6ca 100644 --- a/browser.go +++ b/browser.go @@ -36,7 +36,8 @@ import ( // the [NewBrowserService] method instead. type BrowserService struct { Options []option.RequestOption - // Stream live telemetry events from a browser session. + // Stream live telemetry events from a browser session, and manage the destinations + // sessions export them to. Telemetry BrowserTelemetryService // Record and manage browser session video replays. Replays BrowserReplayService diff --git a/browsertelemetry.go b/browsertelemetry.go index 02a93b9..bceb98b 100644 --- a/browsertelemetry.go +++ b/browsertelemetry.go @@ -22,7 +22,8 @@ import ( "github.com/kernel/kernel-go-sdk/shared/constant" ) -// Stream live telemetry events from a browser session. +// Stream live telemetry events from a browser session, and manage the destinations +// sessions export them to. // // BrowserTelemetryService contains methods and other services that help with // interacting with the kernel API. diff --git a/client.go b/client.go index 48b3721..9827a52 100644 --- a/client.go +++ b/client.go @@ -30,8 +30,9 @@ type Client struct { // Create and manage browser sessions. Browsers BrowserService // Create, list, retrieve, and delete browser profiles. - Profiles ProfileService - Auth AuthService + Profiles ProfileService + Auth AuthService + Telemetry TelemetryService // Create and manage proxy configurations for routing browser traffic. Proxies ProxyService // Create, list, retrieve, and delete browser extensions. @@ -94,6 +95,7 @@ func NewClient(opts ...option.RequestOption) (r Client) { r.Browsers = NewBrowserService(opts...) r.Profiles = NewProfileService(opts...) r.Auth = NewAuthService(opts...) + r.Telemetry = NewTelemetryService(opts...) r.Proxies = NewProxyService(opts...) r.Extensions = NewExtensionService(opts...) r.BrowserPools = NewBrowserPoolService(opts...) diff --git a/telemetry.go b/telemetry.go new file mode 100644 index 0000000..076adbf --- /dev/null +++ b/telemetry.go @@ -0,0 +1,30 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +package kernel + +import ( + "github.com/kernel/kernel-go-sdk/option" +) + +// TelemetryService contains methods and other services that help with interacting +// with the kernel API. +// +// Note, unlike clients, this service does not read variables from the environment +// automatically. You should not instantiate this service directly, and instead use +// the [NewTelemetryService] method instead. +type TelemetryService struct { + Options []option.RequestOption + // Stream live telemetry events from a browser session, and manage the destinations + // sessions export them to. + Destinations TelemetryDestinationService +} + +// NewTelemetryService generates a new service that applies the given options to +// each request. These options are applied after the parent client's options (if +// there is one), and before any request-specific options. +func NewTelemetryService(opts ...option.RequestOption) (r TelemetryService) { + r = TelemetryService{} + r.Options = opts + r.Destinations = NewTelemetryDestinationService(opts...) + return +} diff --git a/telemetrydestination.go b/telemetrydestination.go new file mode 100644 index 0000000..8477b1f --- /dev/null +++ b/telemetrydestination.go @@ -0,0 +1,241 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +package kernel + +import ( + "context" + "errors" + "fmt" + "net/http" + "net/url" + "slices" + "time" + + "github.com/kernel/kernel-go-sdk/internal/apijson" + "github.com/kernel/kernel-go-sdk/internal/apiquery" + "github.com/kernel/kernel-go-sdk/internal/requestconfig" + "github.com/kernel/kernel-go-sdk/option" + "github.com/kernel/kernel-go-sdk/packages/pagination" + "github.com/kernel/kernel-go-sdk/packages/param" + "github.com/kernel/kernel-go-sdk/packages/respjson" +) + +// Stream live telemetry events from a browser session, and manage the destinations +// sessions export them to. +// +// TelemetryDestinationService contains methods and other services that help with +// interacting with the kernel API. +// +// Note, unlike clients, this service does not read variables from the environment +// automatically. You should not instantiate this service directly, and instead use +// the [NewTelemetryDestinationService] method instead. +type TelemetryDestinationService struct { + Options []option.RequestOption +} + +// NewTelemetryDestinationService generates a new service that applies the given +// options to each request. These options are applied after the parent client's +// options (if there is one), and before any request-specific options. +func NewTelemetryDestinationService(opts ...option.RequestOption) (r TelemetryDestinationService) { + r = TelemetryDestinationService{} + r.Options = opts + return +} + +// Create an OTLP export destination in the resolved project. Names must be unique +// within the project. +func (r *TelemetryDestinationService) New(ctx context.Context, body TelemetryDestinationNewParams, opts ...option.RequestOption) (res *OtlpDestination, err error) { + opts = slices.Concat(r.Options, opts) + path := "telemetry/destinations" + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) + return res, err +} + +// Retrieve a single OTLP destination in the resolved project by its ID or name. +func (r *TelemetryDestinationService) Get(ctx context.Context, idOrName string, opts ...option.RequestOption) (res *OtlpDestination, err error) { + opts = slices.Concat(r.Options, opts) + if idOrName == "" { + err = errors.New("missing required id_or_name parameter") + return nil, err + } + path := fmt.Sprintf("telemetry/destinations/%s", idOrName) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) + return res, err +} + +// Update an OTLP destination. Sessions already exporting to it pick up the new +// values without restarting, which makes this the way to rotate credentials +// without interrupting export. +// +// Names must be unique within the project. Renaming is refused with a 409 while a +// managed auth connection selects this destination by name, since that connection +// resolves the name on every login. Every other field, including `headers`, stays +// editable. +func (r *TelemetryDestinationService) Update(ctx context.Context, idOrName string, body TelemetryDestinationUpdateParams, opts ...option.RequestOption) (res *OtlpDestination, err error) { + opts = slices.Concat(r.Options, opts) + if idOrName == "" { + err = errors.New("missing required id_or_name parameter") + return nil, err + } + path := fmt.Sprintf("telemetry/destinations/%s", idOrName) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPatch, path, body, &res, opts...) + return res, err +} + +// List OTLP export destinations in the resolved project. +func (r *TelemetryDestinationService) List(ctx context.Context, query TelemetryDestinationListParams, opts ...option.RequestOption) (res *pagination.OffsetPagination[OtlpDestination], err error) { + var raw *http.Response + opts = slices.Concat(r.Options, opts) + opts = append([]option.RequestOption{option.WithResponseInto(&raw)}, opts...) + path := "telemetry/destinations" + cfg, err := requestconfig.NewRequestConfig(ctx, http.MethodGet, path, query, &res, opts...) + if err != nil { + return nil, err + } + err = cfg.Execute() + if err != nil { + return nil, err + } + res.SetPageConfig(cfg, raw) + return res, nil +} + +// List OTLP export destinations in the resolved project. +func (r *TelemetryDestinationService) ListAutoPaging(ctx context.Context, query TelemetryDestinationListParams, opts ...option.RequestOption) *pagination.OffsetPaginationAutoPager[OtlpDestination] { + return pagination.NewOffsetPaginationAutoPager(r.List(ctx, query, opts...)) +} + +// Delete an OTLP destination. Sessions bound to it are still exporting, so the +// delete is refused with a 409 while any exist; either wait for those sessions to +// end or delete them first. It is refused the same way while a managed auth +// connection still selects it, because that connection re-resolves the destination +// on every login, and while a managed auth login using it is still in progress. +func (r *TelemetryDestinationService) Delete(ctx context.Context, idOrName string, opts ...option.RequestOption) (err error) { + opts = slices.Concat(r.Options, opts) + opts = append([]option.RequestOption{option.WithHeader("Accept", "*/*")}, opts...) + if idOrName == "" { + err = errors.New("missing required id_or_name parameter") + return err + } + path := fmt.Sprintf("telemetry/destinations/%s", idOrName) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, nil, opts...) + return err +} + +// An OTLP endpoint to export browser session telemetry to. Reference one from +// `telemetry.export.otlp.destination` when creating a browser to export that +// session's captured telemetry to it. +type OtlpDestination struct { + ID string `json:"id" api:"required"` + CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"` + // OTLP/HTTP endpoint telemetry is sent to. + Endpoint string `json:"endpoint" api:"required"` + // Headers sent with each export request. Names are returned in canonical form + // (`Authorization`, not `authorization`). Values are returned redacted as empty + // strings, so the keys are visible but the credentials are not. + Headers map[string]string `json:"headers" api:"required"` + // Unique within the project. Usable in place of the ID when selecting a + // destination, so it cannot be shaped like an ID. + Name string `json:"name" api:"required"` + UpdatedAt time.Time `json:"updated_at" api:"required" format:"date-time"` + Description string `json:"description"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + ID respjson.Field + CreatedAt respjson.Field + Endpoint respjson.Field + Headers respjson.Field + Name respjson.Field + UpdatedAt respjson.Field + Description respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r OtlpDestination) RawJSON() string { return r.JSON.raw } +func (r *OtlpDestination) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type TelemetryDestinationNewParams struct { + // Base endpoint of the OTLP/HTTP collector, without a signal path. Kernel appends + // the signal path itself, so pass `https://api.honeycomb.io` rather than + // `https://api.honeycomb.io/v1/logs`. If your provider's docs give you a + // signal-specific URL, drop the trailing `/v1/logs`, `/v1/traces`, or + // `/v1/metrics` — an endpoint that already carries one is rejected. + // + // Must be http or https, must resolve to a public address, and must carry no query + // string or fragment. Examples: `https://api.honeycomb.io`, + // `https://otlp-gateway-prod-us-east-0.grafana.net/otlp`, + // `https://otlp.datadoghq.com` (Datadog's OTLP intake for US1, not its logs + // intake). + Endpoint string `json:"endpoint" api:"required"` + // Unique within the project. + Name string `json:"name" api:"required"` + Description param.Opt[string] `json:"description,omitzero"` + // Headers sent with each export request, typically an ingestion key. Encrypted at + // rest and returned redacted. Names and values must be valid HTTP header tokens, + // and the names and values together cannot exceed 8192 bytes. Names are matched + // case-insensitively and stored canonicalized, so supplying two spellings of one + // header is rejected. + Headers map[string]string `json:"headers,omitzero"` + paramObj +} + +func (r TelemetryDestinationNewParams) MarshalJSON() (data []byte, err error) { + type shadow TelemetryDestinationNewParams + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *TelemetryDestinationNewParams) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type TelemetryDestinationUpdateParams struct { + Description param.Opt[string] `json:"description,omitzero"` + // Base endpoint of the OTLP/HTTP collector, without a signal path. Same rules as + // on create. + Endpoint param.Opt[string] `json:"endpoint,omitzero"` + Name param.Opt[string] `json:"name,omitzero"` + // Edits stored headers key by key rather than replacing the map. A string value + // adds or replaces that header, `null` deletes it, and any key you omit is left as + // it is. Names are matched case-insensitively, so `authorization` replaces a + // stored `Authorization` rather than adding a second entry. This is the credential + // rotation path; sessions already exporting pick up the new values without + // restarting. Names and values must be valid HTTP header tokens, and the names and + // values together cannot exceed 8192 bytes. + Headers map[string]string `json:"headers,omitzero"` + paramObj +} + +func (r TelemetryDestinationUpdateParams) MarshalJSON() (data []byte, err error) { + type shadow TelemetryDestinationUpdateParams + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *TelemetryDestinationUpdateParams) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +type TelemetryDestinationListParams struct { + // Limit the number of destinations to return. + Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` + // Exact-match filter on destination name using the database collation. In + // production, matching is case- and accent-insensitive. + Name param.Opt[string] `query:"name,omitzero" json:"-"` + // Offset the number of destinations to return. + Offset param.Opt[int64] `query:"offset,omitzero" json:"-"` + // Case-insensitive substring match against destination name or endpoint. IDs match + // by exact value. + Query param.Opt[string] `query:"query,omitzero" json:"-"` + paramObj +} + +// URLQuery serializes [TelemetryDestinationListParams]'s query parameters as +// `url.Values`. +func (r TelemetryDestinationListParams) URLQuery() (v url.Values, err error) { + return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{ + ArrayFormat: apiquery.ArrayQueryFormatComma, + NestedFormat: apiquery.NestedQueryFormatBrackets, + }) +} diff --git a/telemetrydestination_test.go b/telemetrydestination_test.go new file mode 100644 index 0000000..039773b --- /dev/null +++ b/telemetrydestination_test.go @@ -0,0 +1,152 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +package kernel_test + +import ( + "context" + "errors" + "os" + "testing" + + "github.com/kernel/kernel-go-sdk" + "github.com/kernel/kernel-go-sdk/internal/testutil" + "github.com/kernel/kernel-go-sdk/option" +) + +func TestTelemetryDestinationNewWithOptionalParams(t *testing.T) { + t.Skip("Mock server tests are disabled") + baseURL := "http://localhost:4010" + if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { + baseURL = envURL + } + if !testutil.CheckTestServer(t, baseURL) { + return + } + client := kernel.NewClient( + option.WithBaseURL(baseURL), + option.WithAPIKey("My API Key"), + ) + _, err := client.Telemetry.Destinations.New(context.TODO(), kernel.TelemetryDestinationNewParams{ + Endpoint: "x", + Name: "name", + Description: kernel.String("description"), + Headers: map[string]string{ + "foo": "string", + }, + }) + if err != nil { + var apierr *kernel.Error + if errors.As(err, &apierr) { + t.Log(string(apierr.DumpRequest(true))) + } + t.Fatalf("err should be nil: %s", err.Error()) + } +} + +func TestTelemetryDestinationGet(t *testing.T) { + t.Skip("Mock server tests are disabled") + baseURL := "http://localhost:4010" + if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { + baseURL = envURL + } + if !testutil.CheckTestServer(t, baseURL) { + return + } + client := kernel.NewClient( + option.WithBaseURL(baseURL), + option.WithAPIKey("My API Key"), + ) + _, err := client.Telemetry.Destinations.Get(context.TODO(), "id_or_name") + if err != nil { + var apierr *kernel.Error + if errors.As(err, &apierr) { + t.Log(string(apierr.DumpRequest(true))) + } + t.Fatalf("err should be nil: %s", err.Error()) + } +} + +func TestTelemetryDestinationUpdateWithOptionalParams(t *testing.T) { + t.Skip("Mock server tests are disabled") + baseURL := "http://localhost:4010" + if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { + baseURL = envURL + } + if !testutil.CheckTestServer(t, baseURL) { + return + } + client := kernel.NewClient( + option.WithBaseURL(baseURL), + option.WithAPIKey("My API Key"), + ) + _, err := client.Telemetry.Destinations.Update( + context.TODO(), + "id_or_name", + kernel.TelemetryDestinationUpdateParams{ + Description: kernel.String("description"), + Endpoint: kernel.String("x"), + Headers: map[string]string{ + "foo": "string", + }, + Name: kernel.String("name"), + }, + ) + if err != nil { + var apierr *kernel.Error + if errors.As(err, &apierr) { + t.Log(string(apierr.DumpRequest(true))) + } + t.Fatalf("err should be nil: %s", err.Error()) + } +} + +func TestTelemetryDestinationListWithOptionalParams(t *testing.T) { + t.Skip("Mock server tests are disabled") + baseURL := "http://localhost:4010" + if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { + baseURL = envURL + } + if !testutil.CheckTestServer(t, baseURL) { + return + } + client := kernel.NewClient( + option.WithBaseURL(baseURL), + option.WithAPIKey("My API Key"), + ) + _, err := client.Telemetry.Destinations.List(context.TODO(), kernel.TelemetryDestinationListParams{ + Limit: kernel.Int(1), + Name: kernel.String("name"), + Offset: kernel.Int(0), + Query: kernel.String("query"), + }) + if err != nil { + var apierr *kernel.Error + if errors.As(err, &apierr) { + t.Log(string(apierr.DumpRequest(true))) + } + t.Fatalf("err should be nil: %s", err.Error()) + } +} + +func TestTelemetryDestinationDelete(t *testing.T) { + t.Skip("Mock server tests are disabled") + baseURL := "http://localhost:4010" + if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { + baseURL = envURL + } + if !testutil.CheckTestServer(t, baseURL) { + return + } + client := kernel.NewClient( + option.WithBaseURL(baseURL), + option.WithAPIKey("My API Key"), + ) + err := client.Telemetry.Destinations.Delete(context.TODO(), "id_or_name") + if err != nil { + var apierr *kernel.Error + if errors.As(err, &apierr) { + t.Log(string(apierr.DumpRequest(true))) + } + t.Fatalf("err should be nil: %s", err.Error()) + } +} From 7cd93c2ef29622c32cf16a58c9717c9a47fb4ce1 Mon Sep 17 00:00:00 2001 From: "kernel-internal[bot]" <260533166+kernel-internal[bot]@users.noreply.github.com> Date: Fri, 14 Aug 2026 18:12:14 +0000 Subject: [PATCH 4/4] release: 0.91.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 9 +++++++++ README.md | 2 +- internal/version.go | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index f286375..29c535c 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.90.0" + ".": "0.91.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index b8df63d..ca827fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## [0.91.0](https://github.com/kernel/kernel-go-sdk/compare/v0.90.0...v0.91.0) (2026-08-14) + + +### Features + +* Add customer-facing OTLP destination CRUD API ([25f9b28](https://github.com/kernel/kernel-go-sdk/commit/25f9b283b2ec49a85a973bc267a6bde4c3872a76)) +* Expose configurable browser memory ([cb90eb7](https://github.com/kernel/kernel-go-sdk/commit/cb90eb77d34aaeb9302fb701a6a613d1f3ff51af)) +* Require a name on credential providers and backfill unnamed rows ([1f70e73](https://github.com/kernel/kernel-go-sdk/commit/1f70e735bad95b73c3eb89535479eac45f1c6dc3)) + ## [0.90.0](https://github.com/kernel/kernel-go-sdk/compare/v0.89.0...v0.90.0) (2026-08-12) diff --git a/README.md b/README.md index acdff03..52c3ec4 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Or to pin the version: ```sh -go get -u 'github.com/kernel/kernel-go-sdk@v0.90.0' +go get -u 'github.com/kernel/kernel-go-sdk@v0.91.0' ``` diff --git a/internal/version.go b/internal/version.go index 4e3e961..af7cda6 100644 --- a/internal/version.go +++ b/internal/version.go @@ -2,4 +2,4 @@ package internal -const PackageVersion = "0.90.0" // x-release-please-version +const PackageVersion = "0.91.0" // x-release-please-version