From edcc0e5e25cbce705d36a316b146a6eda30dc4fb Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 9 Jul 2026 23:07:40 +0000 Subject: [PATCH 01/10] docs(openapi): describe unified concurrency limit, deprecate max_pooled_sessions (CUS-275) --- .stats.yml | 4 ++-- organizationlimit.go | 21 +++++++++++---------- projectlimit.go | 23 +++++++++++++++-------- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/.stats.yml b/.stats.yml index 3f7dec3..c702819 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 125 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-ba32039d3975da7aa6d28e5184f0a44c9fbfe36ab7dbc71985d14e2ecc0867b9.yml -openapi_spec_hash: a9f32fc90c2add2ae85af828c298e35b +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-db45aab5b114bc0848eab997c85bfc02a653be9f929f8d090ec24187462733ee.yml +openapi_spec_hash: 82f4282312699f8d54bec207e981efe8 config_hash: 06186eb40e0058a2a87ac251fc07415d diff --git a/organizationlimit.go b/organizationlimit.go index 0860565..b1d5859 100644 --- a/organizationlimit.go +++ b/organizationlimit.go @@ -36,8 +36,9 @@ func NewOrganizationLimitService(opts ...option.RequestOption) (r OrganizationLi return } -// Get the organization's concurrent session ceiling and the default per-project -// concurrency cap applied to projects without an explicit override. +// Get the organization's concurrency limit — the maximum browsers running at once +// across on-demand sessions and browser pool reservations — and the default +// per-project concurrency cap applied to projects without an explicit override. func (r *OrganizationLimitService) Get(ctx context.Context, opts ...option.RequestOption) (res *OrgLimits, err error) { opts = slices.Concat(r.Options, opts) path := "org/limits" @@ -47,8 +48,7 @@ func (r *OrganizationLimitService) Get(ctx context.Context, opts ...option.Reque // Set the default per-project concurrency cap applied to projects without an // explicit override. Set the value to 0 to remove the default; omit to leave it -// unchanged. The default cannot exceed the organization's concurrent session -// ceiling. +// unchanged. The default cannot exceed the organization's concurrency limit. func (r *OrganizationLimitService) Update(ctx context.Context, body OrganizationLimitUpdateParams, opts ...option.RequestOption) (res *OrgLimits, err error) { opts = slices.Concat(r.Options, opts) path := "org/limits" @@ -57,13 +57,14 @@ func (r *OrganizationLimitService) Update(ctx context.Context, body Organization } type OrgLimits struct { - // Default maximum concurrent browser sessions applied to every project that has no + // Default maximum concurrent browsers applied to every project that has no // explicit per-project override. Null means no org-level default, so such projects // are uncapped (only the org-wide limit applies). Applies to existing and newly // created projects. DefaultProjectMaxConcurrentSessions int64 `json:"default_project_max_concurrent_sessions" api:"nullable"` - // The organization's effective concurrent browser session ceiling, from its plan - // or an override. Read-only and shared across all projects in the org; a + // The organization's effective concurrency limit — the maximum browsers running at + // once, covering both on-demand sessions and browser pool reservations — from its + // plan or an override. Read-only and shared across all projects in the org; a // per-project default cannot exceed it. MaxConcurrentSessions int64 `json:"max_concurrent_sessions"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. @@ -82,9 +83,9 @@ func (r *OrgLimits) UnmarshalJSON(data []byte) error { } type UpdateOrgLimitsRequestParam struct { - // Default maximum concurrent browser sessions for projects without an explicit - // override. Set to 0 to remove the default; omit to leave unchanged. Cannot exceed - // the organization's concurrent session ceiling. + // Default maximum concurrent browsers for projects without an explicit override. + // Set to 0 to remove the default; omit to leave unchanged. Cannot exceed the + // organization's concurrency limit. DefaultProjectMaxConcurrentSessions param.Opt[int64] `json:"default_project_max_concurrent_sessions,omitzero"` paramObj } diff --git a/projectlimit.go b/projectlimit.go index ef8de57..ac288fd 100644 --- a/projectlimit.go +++ b/projectlimit.go @@ -69,11 +69,14 @@ type ProjectLimits struct { // Maximum concurrent app invocations for this project. Null means no project-level // cap. MaxConcurrentInvocations int64 `json:"max_concurrent_invocations" api:"nullable"` - // Maximum concurrent browser sessions for this project. Null means no - // project-level cap. - MaxConcurrentSessions int64 `json:"max_concurrent_sessions" api:"nullable"` - // Maximum pooled sessions capacity for this project. Null means no project-level + // Maximum concurrent browsers for this project, covering both on-demand sessions + // (`browsers.create()`) and browser pool reservations. Null means no project-level // cap. + MaxConcurrentSessions int64 `json:"max_concurrent_sessions" api:"nullable"` + // Deprecated: pooled browsers now count toward `max_concurrent_sessions`. Always + // null once the unified concurrency limit is enabled for your organization. + // + // Deprecated: deprecated MaxPooledSessions int64 `json:"max_pooled_sessions" api:"nullable"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { @@ -95,11 +98,15 @@ type UpdateProjectLimitsRequestParam struct { // Maximum concurrent app invocations for this project. Set to 0 to remove the cap; // omit to leave unchanged. MaxConcurrentInvocations param.Opt[int64] `json:"max_concurrent_invocations,omitzero"` - // Maximum concurrent browser sessions for this project. Set to 0 to remove the - // cap; omit to leave unchanged. + // Maximum concurrent browsers for this project, covering both on-demand sessions + // and browser pool reservations. Set to 0 to remove the cap; omit to leave + // unchanged. MaxConcurrentSessions param.Opt[int64] `json:"max_concurrent_sessions,omitzero"` - // Maximum pooled sessions capacity for this project. Set to 0 to remove the cap; - // omit to leave unchanged. + // Deprecated: pooled browsers now count toward `max_concurrent_sessions`. Requests + // that set this field are rejected with a 400 once the unified concurrency limit + // is enabled for your organization. + // + // Deprecated: deprecated MaxPooledSessions param.Opt[int64] `json:"max_pooled_sessions,omitzero"` paramObj } From c2b2b5e5cf318b2d6c9e964b65274f8de4a57a35 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 13:45:51 +0000 Subject: [PATCH 02/10] feat: Add name-only rename for profiles and proxies --- .stats.yml | 8 +- api.md | 3 + profile.go | 38 +++++- profile_test.go | 29 +++++ proxy.go | 302 ++++++++++++++++++++++++++++++++++++++++++++++++ proxy_test.go | 29 +++++ 6 files changed, 404 insertions(+), 5 deletions(-) diff --git a/.stats.yml b/.stats.yml index c702819..09109a9 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 125 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-db45aab5b114bc0848eab997c85bfc02a653be9f929f8d090ec24187462733ee.yml -openapi_spec_hash: 82f4282312699f8d54bec207e981efe8 -config_hash: 06186eb40e0058a2a87ac251fc07415d +configured_endpoints: 127 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-bc33d13e669972493e9ab0da82a71999822dc049eb14b113f446753c917ffcdb.yml +openapi_spec_hash: 133a2e0d0cdc4023f98b3c2e589cf5d8 +config_hash: 77ee715aa17061166f9a02b264a21b8d diff --git a/api.md b/api.md index 43da313..2a11317 100644 --- a/api.md +++ b/api.md @@ -264,6 +264,7 @@ Methods: - client.Profiles.New(ctx context.Context, body kernel.ProfileNewParams) (\*kernel.Profile, error) - client.Profiles.Get(ctx context.Context, idOrName string) (\*kernel.Profile, error) +- client.Profiles.Update(ctx context.Context, idOrName string, body kernel.ProfileUpdateParams) (\*kernel.Profile, error) - client.Profiles.List(ctx context.Context, query kernel.ProfileListParams) (\*pagination.OffsetPagination[kernel.Profile], error) - client.Profiles.Delete(ctx context.Context, idOrName string) error - client.Profiles.Download(ctx context.Context, idOrName string) (\*http.Response, error) @@ -304,6 +305,7 @@ Response Types: - kernel.ProxyNewResponse - kernel.ProxyGetResponse +- kernel.ProxyUpdateResponse - kernel.ProxyListResponse - kernel.ProxyCheckResponse @@ -311,6 +313,7 @@ Methods: - client.Proxies.New(ctx context.Context, body kernel.ProxyNewParams) (\*kernel.ProxyNewResponse, error) - client.Proxies.Get(ctx context.Context, id string) (\*kernel.ProxyGetResponse, error) +- client.Proxies.Update(ctx context.Context, id string, body kernel.ProxyUpdateParams) (\*kernel.ProxyUpdateResponse, error) - client.Proxies.List(ctx context.Context, query kernel.ProxyListParams) (\*pagination.OffsetPagination[kernel.ProxyListResponse], error) - client.Proxies.Delete(ctx context.Context, id string) error - client.Proxies.Check(ctx context.Context, id string, body kernel.ProxyCheckParams) (\*kernel.ProxyCheckResponse, error) diff --git a/profile.go b/profile.go index 58304a9..2e6e3cf 100644 --- a/profile.go +++ b/profile.go @@ -60,6 +60,24 @@ func (r *ProfileService) Get(ctx context.Context, idOrName string, opts ...optio return res, err } +// Update a profile's name. Names must be unique within the logical project; during +// the default-project migration, unscoped profiles and profiles in the org default +// project are treated as the same project. Duplicate-name conflicts are checked +// before update but are best-effort because there is no backing unique index. +// Renaming a profile while a browser session references it by name may prevent +// that session's changes from saving; prefer renaming when the profile is not in +// use. +func (r *ProfileService) Update(ctx context.Context, idOrName string, body ProfileUpdateParams, opts ...option.RequestOption) (res *Profile, 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("profiles/%s", idOrName) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPatch, path, body, &res, opts...) + return res, err +} + // List profiles with optional filtering and pagination. func (r *ProfileService) List(ctx context.Context, query ProfileListParams, opts ...option.RequestOption) (res *pagination.OffsetPagination[Profile], err error) { var raw *http.Response @@ -110,7 +128,9 @@ func (r *ProfileService) Download(ctx context.Context, idOrName string, opts ... } type ProfileNewParams struct { - // Optional name of the profile. Must be unique within the project. + // Optional name of the profile. Must be unique within the logical project; during + // the default-project migration, unscoped profiles and profiles in the org default + // project are treated as the same project. Name param.Opt[string] `json:"name,omitzero"` paramObj } @@ -123,6 +143,22 @@ func (r *ProfileNewParams) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } +type ProfileUpdateParams struct { + // New profile name. Must be unique within the logical project; during the + // default-project migration, unscoped profiles and profiles in the org default + // project are treated as the same project. + Name string `json:"name" api:"required"` + paramObj +} + +func (r ProfileUpdateParams) MarshalJSON() (data []byte, err error) { + type shadow ProfileUpdateParams + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *ProfileUpdateParams) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + type ProfileListParams struct { // Limit the number of profiles to return. Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` diff --git a/profile_test.go b/profile_test.go index 179bf75..17b1a4c 100644 --- a/profile_test.go +++ b/profile_test.go @@ -65,6 +65,35 @@ func TestProfileGet(t *testing.T) { } } +func TestProfileUpdate(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.Profiles.Update( + context.TODO(), + "id_or_name", + kernel.ProfileUpdateParams{ + Name: "my-renamed-profile", + }, + ) + 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 TestProfileListWithOptionalParams(t *testing.T) { t.Skip("Mock server tests are disabled") baseURL := "http://localhost:4010" diff --git a/proxy.go b/proxy.go index 2de2856..037d47f 100644 --- a/proxy.go +++ b/proxy.go @@ -62,6 +62,21 @@ func (r *ProxyService) Get(ctx context.Context, id string, opts ...option.Reques return res, err } +// Update a proxy's name. Proxy names are not unique and are not ID-or-name +// addressable on this endpoint; duplicate names are allowed. Name-based +// session-create lookups can remain ambiguous until callers resolve proxies by ID +// or the API adds a stronger uniqueness contract. +func (r *ProxyService) Update(ctx context.Context, id string, body ProxyUpdateParams, opts ...option.RequestOption) (res *ProxyUpdateResponse, err error) { + opts = slices.Concat(r.Options, opts) + if id == "" { + err = errors.New("missing required id parameter") + return nil, err + } + path := fmt.Sprintf("proxies/%s", id) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodPatch, path, body, &res, opts...) + return res, err +} + // List proxies in the resolved project. func (r *ProxyService) List(ctx context.Context, query ProxyListParams, opts ...option.RequestOption) (res *pagination.OffsetPagination[ProxyListResponse], err error) { var raw *http.Response @@ -659,6 +674,278 @@ const ( ProxyGetResponseStatusUnavailable ProxyGetResponseStatus = "unavailable" ) +// Configuration for routing traffic through a proxy. +type ProxyUpdateResponse struct { + // Proxy type to use. In terms of quality for avoiding bot-detection, from best to + // worst: `mobile` > `residential` > `isp` > `datacenter`. + // + // Any of "datacenter", "isp", "residential", "mobile", "custom". + Type ProxyUpdateResponseType `json:"type" api:"required"` + ID string `json:"id"` + // Hostnames that should bypass the parent proxy and connect directly. + BypassHosts []string `json:"bypass_hosts"` + // Configuration specific to the selected proxy `type`. + Config ProxyUpdateResponseConfigUnion `json:"config"` + // IP address that the proxy uses when making requests. + IPAddress string `json:"ip_address"` + // Timestamp of the last health check performed on this proxy. + LastChecked time.Time `json:"last_checked" format:"date-time"` + // Readable name of the proxy. + Name string `json:"name"` + // Protocol to use for the proxy connection. + // + // Any of "http", "https". + Protocol ProxyUpdateResponseProtocol `json:"protocol"` + // Current health status of the proxy. + // + // Any of "available", "unavailable". + Status ProxyUpdateResponseStatus `json:"status"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Type respjson.Field + ID respjson.Field + BypassHosts respjson.Field + Config respjson.Field + IPAddress respjson.Field + LastChecked respjson.Field + Name respjson.Field + Protocol respjson.Field + Status respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r ProxyUpdateResponse) RawJSON() string { return r.JSON.raw } +func (r *ProxyUpdateResponse) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Proxy type to use. In terms of quality for avoiding bot-detection, from best to +// worst: `mobile` > `residential` > `isp` > `datacenter`. +type ProxyUpdateResponseType string + +const ( + ProxyUpdateResponseTypeDatacenter ProxyUpdateResponseType = "datacenter" + ProxyUpdateResponseTypeIsp ProxyUpdateResponseType = "isp" + ProxyUpdateResponseTypeResidential ProxyUpdateResponseType = "residential" + ProxyUpdateResponseTypeMobile ProxyUpdateResponseType = "mobile" + ProxyUpdateResponseTypeCustom ProxyUpdateResponseType = "custom" +) + +// ProxyUpdateResponseConfigUnion contains all possible properties and values from +// [ProxyUpdateResponseConfigDatacenter], [ProxyUpdateResponseConfigIsp], +// [ProxyUpdateResponseConfigResidential], [ProxyUpdateResponseConfigMobile], +// [ProxyUpdateResponseConfigCustom]. +// +// Use the methods beginning with 'As' to cast the union to one of its variants. +type ProxyUpdateResponseConfigUnion struct { + Country string `json:"country"` + // This field is from variant [ProxyUpdateResponseConfigResidential]. + Asn string `json:"asn"` + City string `json:"city"` + // This field is from variant [ProxyUpdateResponseConfigResidential]. + Os string `json:"os"` + State string `json:"state"` + // This field is from variant [ProxyUpdateResponseConfigResidential]. + Zip string `json:"zip"` + // This field is from variant [ProxyUpdateResponseConfigCustom]. + Host string `json:"host"` + // This field is from variant [ProxyUpdateResponseConfigCustom]. + Port int64 `json:"port"` + // This field is from variant [ProxyUpdateResponseConfigCustom]. + HasPassword bool `json:"has_password"` + // This field is from variant [ProxyUpdateResponseConfigCustom]. + Username string `json:"username"` + JSON struct { + Country respjson.Field + Asn respjson.Field + City respjson.Field + Os respjson.Field + State respjson.Field + Zip respjson.Field + Host respjson.Field + Port respjson.Field + HasPassword respjson.Field + Username respjson.Field + raw string + } `json:"-"` +} + +func (u ProxyUpdateResponseConfigUnion) AsDatacenter() (v ProxyUpdateResponseConfigDatacenter) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ProxyUpdateResponseConfigUnion) AsIsp() (v ProxyUpdateResponseConfigIsp) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ProxyUpdateResponseConfigUnion) AsResidential() (v ProxyUpdateResponseConfigResidential) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ProxyUpdateResponseConfigUnion) AsMobile() (v ProxyUpdateResponseConfigMobile) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +func (u ProxyUpdateResponseConfigUnion) AsCustom() (v ProxyUpdateResponseConfigCustom) { + apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v) + return +} + +// Returns the unmodified JSON received from the API +func (u ProxyUpdateResponseConfigUnion) RawJSON() string { return u.JSON.raw } + +func (r *ProxyUpdateResponseConfigUnion) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Configuration for a datacenter proxy. +type ProxyUpdateResponseConfigDatacenter struct { + // ISO 3166 country code. Defaults to US if not provided. + Country string `json:"country"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Country respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r ProxyUpdateResponseConfigDatacenter) RawJSON() string { return r.JSON.raw } +func (r *ProxyUpdateResponseConfigDatacenter) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Configuration for an ISP proxy. +type ProxyUpdateResponseConfigIsp struct { + // ISO 3166 country code. Defaults to US if not provided. + Country string `json:"country"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Country respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r ProxyUpdateResponseConfigIsp) RawJSON() string { return r.JSON.raw } +func (r *ProxyUpdateResponseConfigIsp) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Configuration for residential proxies. +type ProxyUpdateResponseConfigResidential struct { + // Autonomous system number. See https://bgp.potaroo.net/cidr/autnums.html + Asn string `json:"asn"` + // City name (no spaces, e.g. `sanfrancisco`). If provided, `country` must also be + // provided. + City string `json:"city"` + // ISO 3166 country code. + Country string `json:"country"` + // Operating system of the residential device. + // + // Any of "windows", "macos", "android". + // + // Deprecated: deprecated + Os string `json:"os"` + // Two-letter state code. + State string `json:"state"` + // US ZIP code. + Zip string `json:"zip"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Asn respjson.Field + City respjson.Field + Country respjson.Field + Os respjson.Field + State respjson.Field + Zip respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r ProxyUpdateResponseConfigResidential) RawJSON() string { return r.JSON.raw } +func (r *ProxyUpdateResponseConfigResidential) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Configuration for mobile proxies. +type ProxyUpdateResponseConfigMobile struct { + // Provider city alias. Mobile carrier routing can make observed geo vary. + City string `json:"city"` + // ISO 3166 country code + Country string `json:"country"` + // US-only state code. Mobile carrier routing can make observed geo vary. + State string `json:"state"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + City respjson.Field + Country respjson.Field + State respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r ProxyUpdateResponseConfigMobile) RawJSON() string { return r.JSON.raw } +func (r *ProxyUpdateResponseConfigMobile) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Configuration for a custom proxy (e.g., private proxy server). +type ProxyUpdateResponseConfigCustom struct { + // Proxy host address or IP. + Host string `json:"host" api:"required"` + // Proxy port. + Port int64 `json:"port" api:"required"` + // Whether the proxy has a password. + HasPassword bool `json:"has_password"` + // Username for proxy authentication. + Username string `json:"username"` + // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. + JSON struct { + Host respjson.Field + Port respjson.Field + HasPassword respjson.Field + Username respjson.Field + ExtraFields map[string]respjson.Field + raw string + } `json:"-"` +} + +// Returns the unmodified JSON received from the API +func (r ProxyUpdateResponseConfigCustom) RawJSON() string { return r.JSON.raw } +func (r *ProxyUpdateResponseConfigCustom) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + +// Protocol to use for the proxy connection. +type ProxyUpdateResponseProtocol string + +const ( + ProxyUpdateResponseProtocolHTTP ProxyUpdateResponseProtocol = "http" + ProxyUpdateResponseProtocolHTTPS ProxyUpdateResponseProtocol = "https" +) + +// Current health status of the proxy. +type ProxyUpdateResponseStatus string + +const ( + ProxyUpdateResponseStatusAvailable ProxyUpdateResponseStatus = "available" + ProxyUpdateResponseStatusUnavailable ProxyUpdateResponseStatus = "unavailable" +) + // Configuration for routing traffic through a proxy. type ProxyListResponse struct { // Proxy type to use. In terms of quality for avoiding bot-detection, from best to @@ -1486,6 +1773,21 @@ const ( ProxyNewParamsProtocolHTTPS ProxyNewParamsProtocol = "https" ) +type ProxyUpdateParams struct { + // New proxy name. Proxy names are trimmed and length-checked only; duplicates are + // allowed because proxies are updated by ID, not by name. + Name string `json:"name" api:"required"` + paramObj +} + +func (r ProxyUpdateParams) MarshalJSON() (data []byte, err error) { + type shadow ProxyUpdateParams + return param.MarshalObject(r, (*shadow)(&r)) +} +func (r *ProxyUpdateParams) UnmarshalJSON(data []byte) error { + return apijson.UnmarshalRoot(data, r) +} + type ProxyListParams struct { // Limit the number of proxies to return. Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` diff --git a/proxy_test.go b/proxy_test.go index 6775135..272bab1 100644 --- a/proxy_test.go +++ b/proxy_test.go @@ -69,6 +69,35 @@ func TestProxyGet(t *testing.T) { } } +func TestProxyUpdate(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.Proxies.Update( + context.TODO(), + "id", + kernel.ProxyUpdateParams{ + Name: "my-renamed-proxy", + }, + ) + 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 TestProxyListWithOptionalParams(t *testing.T) { t.Skip("Mock server tests are disabled") baseURL := "http://localhost:4010" From fd4fcffa2ad8d35878a189a1a66e9e8aac2df872 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 14:19:09 +0000 Subject: [PATCH 03/10] feat: Document name uniqueness and query match semantics --- .stats.yml | 4 ++-- apikey.go | 5 +++-- authconnection.go | 24 ++++++++++++++++++------ browserpool.go | 3 ++- credential.go | 3 ++- credentialprovider.go | 3 ++- extension.go | 3 ++- profile.go | 2 +- proxy.go | 3 ++- 9 files changed, 34 insertions(+), 16 deletions(-) diff --git a/.stats.yml b/.stats.yml index 09109a9..b058b75 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 127 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-bc33d13e669972493e9ab0da82a71999822dc049eb14b113f446753c917ffcdb.yml -openapi_spec_hash: 133a2e0d0cdc4023f98b3c2e589cf5d8 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-6c7cbaefd8a84ec26a1677681f37041323290080dac3fd1a409bb7cd01dd2ae3.yml +openapi_spec_hash: 75085a25c8a5cdb5417f0dbfad0ed6b6 config_hash: 77ee715aa17061166f9a02b264a21b8d diff --git a/apikey.go b/apikey.go index 314d151..f215164 100644 --- a/apikey.go +++ b/apikey.go @@ -138,7 +138,8 @@ type APIKey struct { ExpiresAt time.Time `json:"expires_at" api:"required" format:"date-time"` // Masked version of the API key MaskedKey string `json:"masked_key" api:"required"` - // API key name + // Label for the API key. API keys are not addressable by name; use the ID or key + // identifier for stable references. Name string `json:"name" api:"required"` // Project identifier for project-scoped API keys. Null means org-wide. ProjectID string `json:"project_id" api:"required"` @@ -210,7 +211,7 @@ func (r *CreatedAPIKey) UnmarshalJSON(data []byte) error { } type APIKeyNewParams struct { - // API key name (1-255 characters) + // Label for the API key (1-255 characters). API keys are not addressable by name. Name string `json:"name" api:"required"` // Number of days until expiry, up to 3650. Use null for never. DaysToExpire param.Opt[int64] `json:"days_to_expire,omitzero"` diff --git a/authconnection.go b/authconnection.go index f275e1f..08a383e 100644 --- a/authconnection.go +++ b/authconnection.go @@ -767,7 +767,9 @@ type ManagedAuthCreateRequestParam struct { // - { provider, auto: true } for external provider domain lookup Credential ManagedAuthCreateRequestCredentialParam `json:"credential,omitzero"` // Proxy selection. Provide either id or name. The proxy must be in the same - // project as the resource referencing it. + // project as the resource referencing it. When selecting by name, the name must + // match exactly one active proxy in the project. Ambiguous names return a 400; use + // id for stable references. Proxy ManagedAuthCreateRequestProxyParam `json:"proxy,omitzero"` paramObj } @@ -806,7 +808,9 @@ func (r *ManagedAuthCreateRequestCredentialParam) UnmarshalJSON(data []byte) err } // Proxy selection. Provide either id or name. The proxy must be in the same -// project as the resource referencing it. +// project as the resource referencing it. When selecting by name, the name must +// match exactly one active proxy in the project. Ambiguous names return a 400; use +// id for stable references. type ManagedAuthCreateRequestProxyParam struct { // Proxy ID ID param.Opt[string] `json:"id,omitzero"` @@ -969,7 +973,9 @@ type ManagedAuthUpdateRequestParam struct { // - { provider, auto: true } for external provider domain lookup Credential ManagedAuthUpdateRequestCredentialParam `json:"credential,omitzero"` // Proxy selection. Provide either id or name. The proxy must be in the same - // project as the resource referencing it. + // project as the resource referencing it. When selecting by name, the name must + // match exactly one active proxy in the project. Ambiguous names return a 400; use + // id for stable references. Proxy ManagedAuthUpdateRequestProxyParam `json:"proxy,omitzero"` paramObj } @@ -1008,7 +1014,9 @@ func (r *ManagedAuthUpdateRequestCredentialParam) UnmarshalJSON(data []byte) err } // Proxy selection. Provide either id or name. The proxy must be in the same -// project as the resource referencing it. +// project as the resource referencing it. When selecting by name, the name must +// match exactly one active proxy in the project. Ambiguous names return a 400; use +// id for stable references. type ManagedAuthUpdateRequestProxyParam struct { // Proxy ID ID param.Opt[string] `json:"id,omitzero"` @@ -1446,7 +1454,9 @@ type AuthConnectionLoginParams struct { // When omitted, the connection's record_session default is used. RecordSession param.Opt[bool] `json:"record_session,omitzero"` // Proxy selection. Provide either id or name. The proxy must be in the same - // project as the resource referencing it. + // project as the resource referencing it. When selecting by name, the name must + // match exactly one active proxy in the project. Ambiguous names return a 400; use + // id for stable references. Proxy AuthConnectionLoginParamsProxy `json:"proxy,omitzero"` paramObj } @@ -1460,7 +1470,9 @@ func (r *AuthConnectionLoginParams) UnmarshalJSON(data []byte) error { } // Proxy selection. Provide either id or name. The proxy must be in the same -// project as the resource referencing it. +// project as the resource referencing it. When selecting by name, the name must +// match exactly one active proxy in the project. Ambiguous names return a 400; use +// id for stable references. type AuthConnectionLoginParamsProxy struct { // Proxy ID ID param.Opt[string] `json:"id,omitzero"` diff --git a/browserpool.go b/browserpool.go index 915987d..e8db785 100644 --- a/browserpool.go +++ b/browserpool.go @@ -619,7 +619,8 @@ type BrowserPoolListParams struct { Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` // Offset the number of browser pools to return. Offset param.Opt[int64] `query:"offset,omitzero" json:"-"` - // Search browser pools by name or ID. + // Case-insensitive substring match against browser pool name. IDs match by exact + // value. Query param.Opt[string] `query:"query,omitzero" json:"-"` paramObj } diff --git a/credential.go b/credential.go index c8325e0..1f9cc34 100644 --- a/credential.go +++ b/credential.go @@ -288,7 +288,8 @@ type CredentialListParams struct { Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` // Number of results to skip Offset param.Opt[int64] `query:"offset,omitzero" json:"-"` - // Search credentials by name, domain, or ID. + // Case-insensitive substring match against credential name or domain. IDs match by + // exact value. Query param.Opt[string] `query:"query,omitzero" json:"-"` paramObj } diff --git a/credentialprovider.go b/credentialprovider.go index fc8b35c..77318a2 100644 --- a/credentialprovider.go +++ b/credentialprovider.go @@ -361,7 +361,8 @@ type CredentialProviderListParams struct { Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` // Offset the number of credential providers to return. Offset param.Opt[int64] `query:"offset,omitzero" json:"-"` - // Search credential providers by name or ID. + // Case-insensitive substring match against credential provider name. IDs match by + // exact value. Query param.Opt[string] `query:"query,omitzero" json:"-"` paramObj } diff --git a/extension.go b/extension.go index 8bac50e..672a0c8 100644 --- a/extension.go +++ b/extension.go @@ -245,7 +245,8 @@ type ExtensionListParams struct { Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` // Offset the number of extensions to return. Offset param.Opt[int64] `query:"offset,omitzero" json:"-"` - // Search extensions by name or ID. + // Case-insensitive substring match against extension name. IDs match by exact + // value. Query param.Opt[string] `query:"query,omitzero" json:"-"` paramObj } diff --git a/profile.go b/profile.go index 2e6e3cf..0248006 100644 --- a/profile.go +++ b/profile.go @@ -164,7 +164,7 @@ type ProfileListParams struct { Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` // Offset the number of profiles to return. Offset param.Opt[int64] `query:"offset,omitzero" json:"-"` - // Search profiles by name or ID. + // Case-insensitive substring match against profile name or ID. Query param.Opt[string] `query:"query,omitzero" json:"-"` paramObj } diff --git a/proxy.go b/proxy.go index 037d47f..3655780 100644 --- a/proxy.go +++ b/proxy.go @@ -1793,7 +1793,8 @@ type ProxyListParams struct { Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` // Offset the number of proxies to return. Offset param.Opt[int64] `query:"offset,omitzero" json:"-"` - // Search proxies by name, host, IP address, or ID. + // Case-insensitive substring match against proxy name, host, or IP address. IDs + // match by exact value. Query param.Opt[string] `query:"query,omitzero" json:"-"` paramObj } From 6ffae2ffa5a381af12ff4776ac3d590ed1a724ef Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 14:37:14 +0000 Subject: [PATCH 04/10] feat: Add exact-match name filter to list endpoints --- .stats.yml | 4 ++-- apikey.go | 5 +++++ apikey_test.go | 1 + browserpool.go | 5 +++++ browserpool_test.go | 1 + extension.go | 5 +++++ extension_test.go | 1 + profile.go | 5 +++++ profile_test.go | 1 + project.go | 3 +++ project_test.go | 1 + proxy.go | 4 ++++ proxy_test.go | 1 + 13 files changed, 35 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index b058b75..f7ef7fe 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 127 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-6c7cbaefd8a84ec26a1677681f37041323290080dac3fd1a409bb7cd01dd2ae3.yml -openapi_spec_hash: 75085a25c8a5cdb5417f0dbfad0ed6b6 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-b20fcf2fc1cdb91b51ffd354adcd12d63b950ea98b69e13bee6a78a58498c2cd.yml +openapi_spec_hash: bc8b527a963dd2c2d74b6f9e6ca56652 config_hash: 77ee715aa17061166f9a02b264a21b8d diff --git a/apikey.go b/apikey.go index f215164..03179be 100644 --- a/apikey.go +++ b/apikey.go @@ -263,6 +263,11 @@ type APIKeyListParams struct { IncludeDeleted param.Opt[bool] `query:"include_deleted,omitzero" json:"-"` // Maximum number of results to return Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` + // Exact-match filter on API key name using the database collation. In production, + // matching is case- and accent-insensitive. Names are not required to be unique, + // so multiple keys may match. When status=all or include_deleted=true is set, + // soft-deleted keys with the same name may also match. + Name param.Opt[string] `query:"name,omitzero" json:"-"` // Number of results to skip Offset param.Opt[int64] `query:"offset,omitzero" json:"-"` // Case-insensitive substring match against API key name, creator, and project. API diff --git a/apikey_test.go b/apikey_test.go index 24d41c6..cd8c963 100644 --- a/apikey_test.go +++ b/apikey_test.go @@ -114,6 +114,7 @@ func TestAPIKeyListWithOptionalParams(t *testing.T) { _, err := client.APIKeys.List(context.TODO(), kernel.APIKeyListParams{ IncludeDeleted: kernel.Bool(true), Limit: kernel.Int(100), + Name: kernel.String("name"), Offset: kernel.Int(0), Query: kernel.String("query"), SortBy: kernel.APIKeyListParamsSortByCreatedAt, diff --git a/browserpool.go b/browserpool.go index e8db785..722b9ec 100644 --- a/browserpool.go +++ b/browserpool.go @@ -617,6 +617,11 @@ func (r *BrowserPoolUpdateParamsProfile) UnmarshalJSON(data []byte) error { type BrowserPoolListParams struct { // Limit the number of browser pools to return. Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` + // Exact-match filter on browser pool name using the database collation. In + // production, matching is case- and accent-insensitive. During the default-project + // migration, unscoped requests prefer a concrete default-project browser pool over + // a legacy unscoped browser pool with the same name. + Name param.Opt[string] `query:"name,omitzero" json:"-"` // Offset the number of browser pools to return. Offset param.Opt[int64] `query:"offset,omitzero" json:"-"` // Case-insensitive substring match against browser pool name. IDs match by exact diff --git a/browserpool_test.go b/browserpool_test.go index d144597..2f4c0a5 100644 --- a/browserpool_test.go +++ b/browserpool_test.go @@ -157,6 +157,7 @@ func TestBrowserPoolListWithOptionalParams(t *testing.T) { ) _, err := client.BrowserPools.List(context.TODO(), kernel.BrowserPoolListParams{ Limit: kernel.Int(1), + Name: kernel.String("name"), Offset: kernel.Int(0), Query: kernel.String("query"), }) diff --git a/extension.go b/extension.go index 672a0c8..3102cdd 100644 --- a/extension.go +++ b/extension.go @@ -243,6 +243,11 @@ func (r *ExtensionUploadResponse) UnmarshalJSON(data []byte) error { type ExtensionListParams struct { // Limit the number of extensions to return. Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` + // Exact-match filter on extension name using the database collation. In + // production, matching is case- and accent-insensitive. During the default-project + // migration, unscoped requests prefer a concrete default-project extension over a + // legacy unscoped extension with the same name. + Name param.Opt[string] `query:"name,omitzero" json:"-"` // Offset the number of extensions to return. Offset param.Opt[int64] `query:"offset,omitzero" json:"-"` // Case-insensitive substring match against extension name. IDs match by exact diff --git a/extension_test.go b/extension_test.go index 1944009..dfebd5c 100644 --- a/extension_test.go +++ b/extension_test.go @@ -32,6 +32,7 @@ func TestExtensionListWithOptionalParams(t *testing.T) { ) _, err := client.Extensions.List(context.TODO(), kernel.ExtensionListParams{ Limit: kernel.Int(1), + Name: kernel.String("name"), Offset: kernel.Int(0), Query: kernel.String("query"), }) diff --git a/profile.go b/profile.go index 0248006..54323c2 100644 --- a/profile.go +++ b/profile.go @@ -162,6 +162,11 @@ func (r *ProfileUpdateParams) UnmarshalJSON(data []byte) error { type ProfileListParams struct { // Limit the number of profiles to return. Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` + // Exact-match filter on profile name using the database collation. In production, + // matching is case- and accent-insensitive. During the default-project migration, + // unscoped requests prefer a concrete default-project profile over a legacy + // unscoped profile with the same name. + Name param.Opt[string] `query:"name,omitzero" json:"-"` // Offset the number of profiles to return. Offset param.Opt[int64] `query:"offset,omitzero" json:"-"` // Case-insensitive substring match against profile name or ID. diff --git a/profile_test.go b/profile_test.go index 17b1a4c..842a085 100644 --- a/profile_test.go +++ b/profile_test.go @@ -109,6 +109,7 @@ func TestProfileListWithOptionalParams(t *testing.T) { ) _, err := client.Profiles.List(context.TODO(), kernel.ProfileListParams{ Limit: kernel.Int(1), + Name: kernel.String("name"), Offset: kernel.Int(0), Query: kernel.String("query"), }) diff --git a/project.go b/project.go index e49aad5..7a41fb1 100644 --- a/project.go +++ b/project.go @@ -220,6 +220,9 @@ func (r *ProjectUpdateParams) UnmarshalJSON(data []byte) error { type ProjectListParams struct { // Maximum number of results to return Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` + // Exact-match filter on project name using the database collation. In production, + // matching is case- and accent-insensitive. + Name param.Opt[string] `query:"name,omitzero" json:"-"` // Number of results to skip Offset param.Opt[int64] `query:"offset,omitzero" json:"-"` // Case-insensitive substring match against project name diff --git a/project_test.go b/project_test.go index a8fefba..b40819e 100644 --- a/project_test.go +++ b/project_test.go @@ -110,6 +110,7 @@ func TestProjectListWithOptionalParams(t *testing.T) { ) _, err := client.Projects.List(context.TODO(), kernel.ProjectListParams{ Limit: kernel.Int(100), + Name: kernel.String("name"), Offset: kernel.Int(0), Query: kernel.String("query"), }) diff --git a/proxy.go b/proxy.go index 3655780..fdb2fbf 100644 --- a/proxy.go +++ b/proxy.go @@ -1791,6 +1791,10 @@ func (r *ProxyUpdateParams) UnmarshalJSON(data []byte) error { type ProxyListParams struct { // Limit the number of proxies to return. Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` + // Exact-match filter on proxy name using the database collation. In production, + // matching is case- and accent-insensitive. Names are not required to be unique, + // so multiple proxies may match. + Name param.Opt[string] `query:"name,omitzero" json:"-"` // Offset the number of proxies to return. Offset param.Opt[int64] `query:"offset,omitzero" json:"-"` // Case-insensitive substring match against proxy name, host, or IP address. IDs diff --git a/proxy_test.go b/proxy_test.go index 272bab1..1d9945d 100644 --- a/proxy_test.go +++ b/proxy_test.go @@ -113,6 +113,7 @@ func TestProxyListWithOptionalParams(t *testing.T) { ) _, err := client.Proxies.List(context.TODO(), kernel.ProxyListParams{ Limit: kernel.Int(1), + Name: kernel.String("name"), Offset: kernel.Int(0), Query: kernel.String("query"), }) From b1baff2db6ad583e8998e4ef6d3d711c73817492 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 14:56:02 +0000 Subject: [PATCH 05/10] feat: Make the browser pool OpenAPI contract truthful --- .stats.yml | 4 +-- browserpool.go | 80 +++++++++++++++++++++++++------------------------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/.stats.yml b/.stats.yml index f7ef7fe..c403f2c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 127 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-b20fcf2fc1cdb91b51ffd354adcd12d63b950ea98b69e13bee6a78a58498c2cd.yml -openapi_spec_hash: bc8b527a963dd2c2d74b6f9e6ca56652 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-d7ab1ecb886cb7f86e7ce0926207db423a6650e8e12e7283a71f8682fbb472ae.yml +openapi_spec_hash: 9323b0ba38d2d50b8506be4d7401c04d config_hash: 77ee715aa17061166f9a02b264a21b8d diff --git a/browserpool.go b/browserpool.go index 722b9ec..4784fd1 100644 --- a/browserpool.go +++ b/browserpool.go @@ -206,22 +206,22 @@ func (r *BrowserPool) UnmarshalJSON(data []byte) error { // Configuration used to create all browsers in this pool type BrowserPoolBrowserPoolConfig struct { - // Number of browsers to maintain in the pool. The maximum size is determined by + // Number of browsers maintained in the pool. The maximum size is determined by // your organization's pooled sessions limit (the sum of all pool sizes cannot // exceed your limit). Size int64 `json:"size" api:"required"` // Custom Chrome enterprise policy overrides applied to all browsers in this pool. // Keys are Chrome enterprise policy names; values must match their expected types. // Blocked: kernel-managed policies (extensions, proxy, CDP/automation). See - // https://chromeenterprise.google/policies/ + // https://chromeenterprise.google/policies/ The serialized JSON payload is capped + // at 5 MiB. ChromePolicy map[string]any `json:"chrome_policy"` // List of browser extensions to load into the session. Provide each by id or name. Extensions []shared.BrowserExtension `json:"extensions"` - // Percentage of the pool to fill per minute. Defaults to 10. The cap is 25 for - // most organizations but can be raised per-organization, so only the lower bound - // is enforced here. + // Percentage of the pool to fill per minute. The cap is 25 for most organizations + // but can be raised per-organization, so only the lower bound is enforced here. FillRatePerMinute int64 `json:"fill_rate_per_minute"` - // If true, launches the browser using a headless image. Defaults to false. + // If true, launches the browser using a headless image. Headless bool `json:"headless"` // If true, launches the browser in kiosk mode to hide address bar and tabs in live // view. @@ -234,8 +234,8 @@ type BrowserPoolBrowserPoolConfig struct { // omitted here. Any save_changes value sent on a pool profile is silently ignored // rather than rejected. Profile BrowserPoolBrowserPoolConfigProfile `json:"profile"` - // Optional proxy to associate to the browser session. Must reference a proxy in - // the same project as the browser session. + // Optional proxy associated to the browser session. References a proxy in the same + // project as the browser session. ProxyID string `json:"proxy_id"` // When true, flush idle browsers when the profile the pool uses is updated, so // pool browsers pick up the latest profile data. Requires a profile to be set on @@ -251,7 +251,7 @@ type BrowserPoolBrowserPoolConfig struct { // mechanisms. Stealth bool `json:"stealth"` // Default idle timeout in seconds for browsers acquired from this pool before they - // are destroyed. Defaults to 600 seconds. Minimum 10, maximum 259200 (72 hours). + // are destroyed. Minimum 10, maximum 259200 (72 hours). TimeoutSeconds int64 `json:"timeout_seconds"` // Initial browser window size in pixels with optional refresh rate. If omitted, // image defaults apply (1920x1080@25). For GPU images, the default is @@ -431,7 +431,7 @@ type BrowserPoolNewParams struct { // If true, launches the browser using a headless image. Defaults to false. Headless param.Opt[bool] `json:"headless,omitzero"` // If true, launches the browser in kiosk mode to hide address bar and tabs in live - // view. + // view. Defaults to false. KioskMode param.Opt[bool] `json:"kiosk_mode,omitzero"` // Optional name for the browser pool. Must be unique within the project. Name param.Opt[string] `json:"name,omitzero"` @@ -449,7 +449,7 @@ type BrowserPoolNewParams struct { // chrome:// pages. StartURL param.Opt[string] `json:"start_url,omitzero"` // If true, launches the browser in stealth mode to reduce detection by anti-bot - // mechanisms. + // mechanisms. Defaults to false. Stealth param.Opt[bool] `json:"stealth,omitzero"` // Default idle timeout in seconds for browsers acquired from this pool before they // are destroyed. Defaults to 600 seconds. Minimum 10, maximum 259200 (72 hours). @@ -457,7 +457,8 @@ type BrowserPoolNewParams struct { // Custom Chrome enterprise policy overrides applied to all browsers in this pool. // Keys are Chrome enterprise policy names; values must match their expected types. // Blocked: kernel-managed policies (extensions, proxy, CDP/automation). See - // https://chromeenterprise.google/policies/ + // https://chromeenterprise.google/policies/ The serialized JSON payload is capped + // at 5 MiB. 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"` @@ -521,46 +522,45 @@ type BrowserPoolUpdateParams struct { // pool with that stale configuration until it is discarded (by this flag on a // later update, or by flushing the pool). DiscardAllIdle param.Opt[bool] `json:"discard_all_idle,omitzero"` - // Percentage of the pool to fill per minute. Defaults to 10. The cap is 25 for - // most organizations but can be raised per-organization, so only the lower bound - // is enforced here. + // If provided, replaces the percentage of the pool to fill per minute. The cap is + // 25 for most organizations but can be raised per-organization, so only the lower + // bound is enforced here. FillRatePerMinute param.Opt[int64] `json:"fill_rate_per_minute,omitzero"` - // If true, launches the browser using a headless image. Defaults to false. + // If provided, replaces whether browsers launch using a headless image. Headless param.Opt[bool] `json:"headless,omitzero"` - // If true, launches the browser in kiosk mode to hide address bar and tabs in live - // view. + // If provided, replaces whether browsers launch in kiosk mode. KioskMode param.Opt[bool] `json:"kiosk_mode,omitzero"` - // Optional name for the browser pool. Must be unique within the project. + // If provided, replaces the pool name. Empty string is a no-op; the pool name + // cannot be cleared or reset to empty once assigned. Name param.Opt[string] `json:"name,omitzero"` - // Optional proxy to associate to the browser session. Must reference a proxy in - // the same project as the browser session. + // Empty string clears the previously-selected proxy. Omit this field to leave the + // proxy unchanged. ProxyID param.Opt[string] `json:"proxy_id,omitzero"` - // When true, flush idle browsers when the profile the pool uses is updated, so - // pool browsers pick up the latest profile data. Requires a profile to be set on - // the pool. + // If provided, replaces whether idle browsers are flushed when the profile the + // pool uses is updated. Requires a profile to be set on the pool. RefreshOnProfileUpdate param.Opt[bool] `json:"refresh_on_profile_update,omitzero"` - // Number of browsers to maintain in the pool. The maximum size is determined by - // your organization's pooled sessions limit (the sum of all pool sizes cannot - // exceed your limit). + // If provided, replaces the number of browsers to maintain in the pool. The + // maximum size is determined by your organization's pooled sessions limit (the sum + // of all pool sizes cannot exceed your limit). Size param.Opt[int64] `json:"size,omitzero"` - // Optional URL to navigate to when a new browser is warmed into the pool. - // Best-effort: failures to navigate do not fail pool fill. Only applied to - // newly-warmed browsers; browsers reused via release/acquire keep whatever URL the - // previous lease left them on. Accepts any URL Chromium can resolve, including - // chrome:// pages. + // If provided, replaces the URL to navigate to when a new browser is warmed into + // the pool. Empty string clears the previously-set URL. Omit this field to leave + // it unchanged. StartURL param.Opt[string] `json:"start_url,omitzero"` - // If true, launches the browser in stealth mode to reduce detection by anti-bot - // mechanisms. + // If provided, replaces whether browsers launch in stealth mode. Stealth param.Opt[bool] `json:"stealth,omitzero"` - // Default idle timeout in seconds for browsers acquired from this pool before they - // are destroyed. Defaults to 600 seconds. Minimum 10, maximum 259200 (72 hours). + // If provided, replaces the default idle timeout in seconds for browsers acquired + // from this pool before they are destroyed. Minimum 10, maximum 259200 (72 hours). TimeoutSeconds param.Opt[int64] `json:"timeout_seconds,omitzero"` - // Custom Chrome enterprise policy overrides applied to all browsers in this pool. - // Keys are Chrome enterprise policy names; values must match their expected types. + // If provided, replaces the custom Chrome enterprise policy overrides applied to + // all browsers in this pool. Empty object clears any previously-set policy. Keys + // are Chrome enterprise policy names; values must match their expected types. // Blocked: kernel-managed policies (extensions, proxy, CDP/automation). See - // https://chromeenterprise.google/policies/ + // https://chromeenterprise.google/policies/ The serialized JSON payload is capped + // at 5 MiB. ChromePolicy map[string]any `json:"chrome_policy,omitzero"` - // List of browser extensions to load into the session. Provide each by id or name. + // If provided, replaces the extension list. Empty array clears all + // previously-selected extensions. Omit this field to leave extensions unchanged. Extensions []shared.BrowserExtensionParam `json:"extensions,omitzero"` // Profile configuration for browsers in a pool. Provide either id or name. // Profiles must be created beforehand. Unlike single browser sessions, pools load From a09849ac32a842675babeefdf32d136e18a9d812 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 15:32:35 +0000 Subject: [PATCH 06/10] feat: Persist and echo deployment source identity --- .stats.yml | 4 +- deployment.go | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index c403f2c..f6f6182 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 127 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-d7ab1ecb886cb7f86e7ce0926207db423a6650e8e12e7283a71f8682fbb472ae.yml -openapi_spec_hash: 9323b0ba38d2d50b8506be4d7401c04d +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-d61b5e5ca18ce30a6b4d05483bcd67969ce0f4aee2e9e8c379be4f22f1362b01.yml +openapi_spec_hash: 23121d1c1552e41177b472c4c39d154e config_hash: 77ee715aa17061166f9a02b264a21b8d diff --git a/deployment.go b/deployment.go index 3675b23..d00a5d8 100644 --- a/deployment.go +++ b/deployment.go @@ -167,6 +167,26 @@ type DeploymentStateEventDeployment struct { // API key, OAuth, and managed-auth callers, which receive every key with an empty // string value. Only dashboard sessions receive the actual values. EnvVars map[string]string `json:"env_vars"` + // Hex-encoded SHA-256 checksum of the source archive. For file uploads, this + // hashes the uploaded archive; for GitHub-sourced deployments, this hashes the + // GitHub archive downloaded by the API. Omitted for deployments created before + // this field was recorded. + SourceChecksum string `json:"source_checksum"` + // For GitHub-sourced deployments, the subpath within the repository that was used + // as the deploy root. Omitted when the repo root was used or for file uploads. + SourcePath string `json:"source_path"` + // For GitHub-sourced deployments, the git ref as requested at deploy time (branch, + // tag, or commit SHA — not resolved to a commit). Omitted for file uploads. + SourceRef string `json:"source_ref"` + // Origin of the deployed source code. This is read-only response provenance; + // `file` indicates an uploaded archive and `github` indicates a repository fetched + // by the API. + // + // Any of "file", "github". + SourceType string `json:"source_type"` + // For GitHub-sourced deployments, the repository URL that was fetched. Omitted for + // file uploads. + SourceURL string `json:"source_url"` // Status reason StatusReason string `json:"status_reason"` // Timestamp when the deployment was last updated @@ -179,6 +199,11 @@ type DeploymentStateEventDeployment struct { Status respjson.Field EntrypointRelPath respjson.Field EnvVars respjson.Field + SourceChecksum respjson.Field + SourcePath respjson.Field + SourceRef respjson.Field + SourceType respjson.Field + SourceURL respjson.Field StatusReason respjson.Field UpdatedAt respjson.Field ExtraFields map[string]respjson.Field @@ -210,6 +235,26 @@ type DeploymentNewResponse struct { // API key, OAuth, and managed-auth callers, which receive every key with an empty // string value. Only dashboard sessions receive the actual values. EnvVars map[string]string `json:"env_vars"` + // Hex-encoded SHA-256 checksum of the source archive. For file uploads, this + // hashes the uploaded archive; for GitHub-sourced deployments, this hashes the + // GitHub archive downloaded by the API. Omitted for deployments created before + // this field was recorded. + SourceChecksum string `json:"source_checksum"` + // For GitHub-sourced deployments, the subpath within the repository that was used + // as the deploy root. Omitted when the repo root was used or for file uploads. + SourcePath string `json:"source_path"` + // For GitHub-sourced deployments, the git ref as requested at deploy time (branch, + // tag, or commit SHA — not resolved to a commit). Omitted for file uploads. + SourceRef string `json:"source_ref"` + // Origin of the deployed source code. This is read-only response provenance; + // `file` indicates an uploaded archive and `github` indicates a repository fetched + // by the API. + // + // Any of "file", "github". + SourceType DeploymentNewResponseSourceType `json:"source_type"` + // For GitHub-sourced deployments, the repository URL that was fetched. Omitted for + // file uploads. + SourceURL string `json:"source_url"` // Status reason StatusReason string `json:"status_reason"` // Timestamp when the deployment was last updated @@ -222,6 +267,11 @@ type DeploymentNewResponse struct { Status respjson.Field EntrypointRelPath respjson.Field EnvVars respjson.Field + SourceChecksum respjson.Field + SourcePath respjson.Field + SourceRef respjson.Field + SourceType respjson.Field + SourceURL respjson.Field StatusReason respjson.Field UpdatedAt respjson.Field ExtraFields map[string]respjson.Field @@ -246,6 +296,16 @@ const ( DeploymentNewResponseStatusStopped DeploymentNewResponseStatus = "stopped" ) +// Origin of the deployed source code. This is read-only response provenance; +// `file` indicates an uploaded archive and `github` indicates a repository fetched +// by the API. +type DeploymentNewResponseSourceType string + +const ( + DeploymentNewResponseSourceTypeFile DeploymentNewResponseSourceType = "file" + DeploymentNewResponseSourceTypeGitHub DeploymentNewResponseSourceType = "github" +) + // Deployment record information. type DeploymentGetResponse struct { // Unique identifier for the deployment @@ -264,6 +324,26 @@ type DeploymentGetResponse struct { // API key, OAuth, and managed-auth callers, which receive every key with an empty // string value. Only dashboard sessions receive the actual values. EnvVars map[string]string `json:"env_vars"` + // Hex-encoded SHA-256 checksum of the source archive. For file uploads, this + // hashes the uploaded archive; for GitHub-sourced deployments, this hashes the + // GitHub archive downloaded by the API. Omitted for deployments created before + // this field was recorded. + SourceChecksum string `json:"source_checksum"` + // For GitHub-sourced deployments, the subpath within the repository that was used + // as the deploy root. Omitted when the repo root was used or for file uploads. + SourcePath string `json:"source_path"` + // For GitHub-sourced deployments, the git ref as requested at deploy time (branch, + // tag, or commit SHA — not resolved to a commit). Omitted for file uploads. + SourceRef string `json:"source_ref"` + // Origin of the deployed source code. This is read-only response provenance; + // `file` indicates an uploaded archive and `github` indicates a repository fetched + // by the API. + // + // Any of "file", "github". + SourceType DeploymentGetResponseSourceType `json:"source_type"` + // For GitHub-sourced deployments, the repository URL that was fetched. Omitted for + // file uploads. + SourceURL string `json:"source_url"` // Status reason StatusReason string `json:"status_reason"` // Timestamp when the deployment was last updated @@ -276,6 +356,11 @@ type DeploymentGetResponse struct { Status respjson.Field EntrypointRelPath respjson.Field EnvVars respjson.Field + SourceChecksum respjson.Field + SourcePath respjson.Field + SourceRef respjson.Field + SourceType respjson.Field + SourceURL respjson.Field StatusReason respjson.Field UpdatedAt respjson.Field ExtraFields map[string]respjson.Field @@ -300,6 +385,16 @@ const ( DeploymentGetResponseStatusStopped DeploymentGetResponseStatus = "stopped" ) +// Origin of the deployed source code. This is read-only response provenance; +// `file` indicates an uploaded archive and `github` indicates a repository fetched +// by the API. +type DeploymentGetResponseSourceType string + +const ( + DeploymentGetResponseSourceTypeFile DeploymentGetResponseSourceType = "file" + DeploymentGetResponseSourceTypeGitHub DeploymentGetResponseSourceType = "github" +) + // Deployment record information. type DeploymentListResponse struct { // Unique identifier for the deployment @@ -318,6 +413,26 @@ type DeploymentListResponse struct { // API key, OAuth, and managed-auth callers, which receive every key with an empty // string value. Only dashboard sessions receive the actual values. EnvVars map[string]string `json:"env_vars"` + // Hex-encoded SHA-256 checksum of the source archive. For file uploads, this + // hashes the uploaded archive; for GitHub-sourced deployments, this hashes the + // GitHub archive downloaded by the API. Omitted for deployments created before + // this field was recorded. + SourceChecksum string `json:"source_checksum"` + // For GitHub-sourced deployments, the subpath within the repository that was used + // as the deploy root. Omitted when the repo root was used or for file uploads. + SourcePath string `json:"source_path"` + // For GitHub-sourced deployments, the git ref as requested at deploy time (branch, + // tag, or commit SHA — not resolved to a commit). Omitted for file uploads. + SourceRef string `json:"source_ref"` + // Origin of the deployed source code. This is read-only response provenance; + // `file` indicates an uploaded archive and `github` indicates a repository fetched + // by the API. + // + // Any of "file", "github". + SourceType DeploymentListResponseSourceType `json:"source_type"` + // For GitHub-sourced deployments, the repository URL that was fetched. Omitted for + // file uploads. + SourceURL string `json:"source_url"` // Status reason StatusReason string `json:"status_reason"` // Timestamp when the deployment was last updated @@ -330,6 +445,11 @@ type DeploymentListResponse struct { Status respjson.Field EntrypointRelPath respjson.Field EnvVars respjson.Field + SourceChecksum respjson.Field + SourcePath respjson.Field + SourceRef respjson.Field + SourceType respjson.Field + SourceURL respjson.Field StatusReason respjson.Field UpdatedAt respjson.Field ExtraFields map[string]respjson.Field @@ -354,6 +474,16 @@ const ( DeploymentListResponseStatusStopped DeploymentListResponseStatus = "stopped" ) +// Origin of the deployed source code. This is read-only response provenance; +// `file` indicates an uploaded archive and `github` indicates a repository fetched +// by the API. +type DeploymentListResponseSourceType string + +const ( + DeploymentListResponseSourceTypeFile DeploymentListResponseSourceType = "file" + DeploymentListResponseSourceTypeGitHub DeploymentListResponseSourceType = "github" +) + // DeploymentFollowResponseUnion contains all possible properties and values from // [shared.LogEvent], [DeploymentStateEvent], // [DeploymentFollowResponseAppVersionSummaryEvent], [shared.ErrorEvent], From fe39910f8d4822e41e4c7e6efac14aff52cc9c39 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 15:59:32 +0000 Subject: [PATCH 07/10] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index f6f6182..38aa69b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 127 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-d61b5e5ca18ce30a6b4d05483bcd67969ce0f4aee2e9e8c379be4f22f1362b01.yml -openapi_spec_hash: 23121d1c1552e41177b472c4c39d154e +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-9143bc729ef60beffa0bbd9b601bb095083e41e23c8994553e69302f586882f5.yml +openapi_spec_hash: bd04c530cfa8188af0e63a784129645d config_hash: 77ee715aa17061166f9a02b264a21b8d From b74cae1d226293704baefb943c213c77b83b409b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 19:28:56 +0000 Subject: [PATCH 08/10] feat: Auto-default refresh_on_profile_update when browser pool profile changes --- .stats.yml | 4 ++-- browserpool.go | 13 ++++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.stats.yml b/.stats.yml index 38aa69b..5882e06 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 127 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-9143bc729ef60beffa0bbd9b601bb095083e41e23c8994553e69302f586882f5.yml -openapi_spec_hash: bd04c530cfa8188af0e63a784129645d +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-25b48b79d356843aeda41e5e5c3c407c5bd5c12f9548500ffc0a6696e6acd941.yml +openapi_spec_hash: f710169690ab7aca30c91968e752cff7 config_hash: 77ee715aa17061166f9a02b264a21b8d diff --git a/browserpool.go b/browserpool.go index 4784fd1..1f63f3f 100644 --- a/browserpool.go +++ b/browserpool.go @@ -238,8 +238,8 @@ type BrowserPoolBrowserPoolConfig struct { // project as the browser session. ProxyID string `json:"proxy_id"` // When true, flush idle browsers when the profile the pool uses is updated, so - // pool browsers pick up the latest profile data. Requires a profile to be set on - // the pool. + // pool browsers pick up the latest profile data. When a profile is provided during + // creation, this defaults to true. Requires a profile to be set on the pool. RefreshOnProfileUpdate bool `json:"refresh_on_profile_update"` // Optional URL to navigate to when a new browser is warmed into the pool. // Best-effort: failures to navigate do not fail pool fill. Only applied to @@ -439,8 +439,8 @@ type BrowserPoolNewParams struct { // the same project as the browser session. ProxyID param.Opt[string] `json:"proxy_id,omitzero"` // When true, flush idle browsers when the profile the pool uses is updated, so - // pool browsers pick up the latest profile data. Requires a profile to be set on - // the pool. + // pool browsers pick up the latest profile data. When a profile is provided during + // creation, this defaults to true. Requires a profile to be set on the pool. RefreshOnProfileUpdate param.Opt[bool] `json:"refresh_on_profile_update,omitzero"` // Optional URL to navigate to when a new browser is warmed into the pool. // Best-effort: failures to navigate do not fail pool fill. Only applied to @@ -537,7 +537,10 @@ type BrowserPoolUpdateParams struct { // proxy unchanged. ProxyID param.Opt[string] `json:"proxy_id,omitzero"` // If provided, replaces whether idle browsers are flushed when the profile the - // pool uses is updated. Requires a profile to be set on the pool. + // pool uses is updated. When the pool's profile reference is changed (including + // newly attached) and this field is omitted, it defaults to true. Re-sending the + // same profile reference leaves this setting unchanged. Clearing the profile also + // disables this setting. Requires a profile to be set on the pool. RefreshOnProfileUpdate param.Opt[bool] `json:"refresh_on_profile_update,omitzero"` // If provided, replaces the number of browsers to maintain in the pool. The // maximum size is determined by your organization's pooled sessions limit (the sum From de83d75e14f7f819f6c6982a7c9833d7a3f45721 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 13 Jul 2026 15:43:38 +0000 Subject: [PATCH 09/10] feat: Support multiple audit log method exclusions --- .stats.yml | 4 ++-- auditlog.go | 8 ++++---- auditlog_test.go | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.stats.yml b/.stats.yml index 5882e06..a855b9c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 127 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-25b48b79d356843aeda41e5e5c3c407c5bd5c12f9548500ffc0a6696e6acd941.yml -openapi_spec_hash: f710169690ab7aca30c91968e752cff7 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-f0003e336fc8dc54d9cac4728c847fb80c32d50a9165738c5b70aa83a09bb0f5.yml +openapi_spec_hash: a2099eec27728b1cfd9032dc71b9bb57 config_hash: 77ee715aa17061166f9a02b264a21b8d diff --git a/auditlog.go b/auditlog.go index e487a18..9096e7c 100644 --- a/auditlog.go +++ b/auditlog.go @@ -132,8 +132,6 @@ type AuditLogListParams struct { Start time.Time `query:"start" api:"required" format:"date-time" json:"-"` // Filter by authentication strategy. AuthStrategy param.Opt[string] `query:"auth_strategy,omitzero" json:"-"` - // Filter out results by HTTP method. - ExcludeMethod param.Opt[string] `query:"exclude_method,omitzero" json:"-"` // Maximum number of results to return. Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` // Filter by HTTP method. @@ -144,6 +142,8 @@ type AuditLogListParams struct { Search param.Opt[string] `query:"search,omitzero" json:"-"` // Filter by service name. Service param.Opt[string] `query:"service,omitzero" json:"-"` + // Filter out results by HTTP method. + ExcludeMethod []string `query:"exclude_method,omitzero" json:"-"` // Additional user IDs to OR into free-text search. SearchUserID []string `query:"search_user_id,omitzero" json:"-"` paramObj @@ -166,8 +166,6 @@ type AuditLogExportChunkParams struct { AuthStrategy param.Opt[string] `query:"auth_strategy,omitzero" json:"-"` // Opaque cursor from X-Next-Cursor for the next chunk of older records. Cursor param.Opt[string] `query:"cursor,omitzero" json:"-"` - // Filter out results by HTTP method. - ExcludeMethod param.Opt[string] `query:"exclude_method,omitzero" json:"-"` // Maximum number of records to return in this chunk. Limit param.Opt[int64] `query:"limit,omitzero" json:"-"` // Filter by HTTP method. @@ -176,6 +174,8 @@ type AuditLogExportChunkParams struct { Search param.Opt[string] `query:"search,omitzero" json:"-"` // Filter by service name. Service param.Opt[string] `query:"service,omitzero" json:"-"` + // Filter out results by HTTP method. + ExcludeMethod []string `query:"exclude_method,omitzero" json:"-"` // Encoding for the returned chunk. // // Any of "jsonl", "jsonl.gz". diff --git a/auditlog_test.go b/auditlog_test.go index a849751..49e1cd2 100644 --- a/auditlog_test.go +++ b/auditlog_test.go @@ -35,7 +35,7 @@ func TestAuditLogListWithOptionalParams(t *testing.T) { End: time.Now(), Start: time.Now(), AuthStrategy: kernel.String("auth_strategy"), - ExcludeMethod: kernel.String("exclude_method"), + ExcludeMethod: []string{"string"}, Limit: kernel.Int(1), Method: kernel.String("method"), PageToken: kernel.String("page_token"), @@ -68,7 +68,7 @@ func TestAuditLogExportChunkWithOptionalParams(t *testing.T) { Start: time.Now(), AuthStrategy: kernel.String("auth_strategy"), Cursor: kernel.String("cursor"), - ExcludeMethod: kernel.String("exclude_method"), + ExcludeMethod: []string{"string"}, Format: kernel.AuditLogExportChunkParamsFormatJSONL, Limit: kernel.Int(1), Method: kernel.String("method"), From fbfb965f7a56305351d77806445c52130205f0f9 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 13 Jul 2026 15:44:08 +0000 Subject: [PATCH 10/10] release: 0.77.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 19 +++++++++++++++++++ README.md | 2 +- internal/version.go | 2 +- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index aa39267..5c03edc 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.76.0" + ".": "0.77.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 239a503..f30dfde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +## 0.77.0 (2026-07-13) + +Full Changelog: [v0.76.0...v0.77.0](https://github.com/kernel/kernel-go-sdk/compare/v0.76.0...v0.77.0) + +### Features + +* Add exact-match name filter to list endpoints ([6ffae2f](https://github.com/kernel/kernel-go-sdk/commit/6ffae2ffa5a381af12ff4776ac3d590ed1a724ef)) +* Add name-only rename for profiles and proxies ([c2b2b5e](https://github.com/kernel/kernel-go-sdk/commit/c2b2b5e5cf318b2d6c9e964b65274f8de4a57a35)) +* Auto-default refresh_on_profile_update when browser pool profile changes ([b74cae1](https://github.com/kernel/kernel-go-sdk/commit/b74cae1d226293704baefb943c213c77b83b409b)) +* Document name uniqueness and query match semantics ([fd4fcff](https://github.com/kernel/kernel-go-sdk/commit/fd4fcffa2ad8d35878a189a1a66e9e8aac2df872)) +* Make the browser pool OpenAPI contract truthful ([b1baff2](https://github.com/kernel/kernel-go-sdk/commit/b1baff2db6ad583e8998e4ef6d3d711c73817492)) +* Persist and echo deployment source identity ([a09849a](https://github.com/kernel/kernel-go-sdk/commit/a09849ac32a842675babeefdf32d136e18a9d812)) +* Support multiple audit log method exclusions ([de83d75](https://github.com/kernel/kernel-go-sdk/commit/de83d75e14f7f819f6c6982a7c9833d7a3f45721)) + + +### Documentation + +* **openapi:** describe unified concurrency limit, deprecate max_pooled_sessions (CUS-275) ([edcc0e5](https://github.com/kernel/kernel-go-sdk/commit/edcc0e5e25cbce705d36a316b146a6eda30dc4fb)) + ## 0.76.0 (2026-07-09) Full Changelog: [v0.75.0...v0.76.0](https://github.com/kernel/kernel-go-sdk/compare/v0.75.0...v0.76.0) diff --git a/README.md b/README.md index 7e5f139..08388b5 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.76.0' +go get -u 'github.com/kernel/kernel-go-sdk@v0.77.0' ``` diff --git a/internal/version.go b/internal/version.go index b3372db..7dfcf69 100644 --- a/internal/version.go +++ b/internal/version.go @@ -2,4 +2,4 @@ package internal -const PackageVersion = "0.76.0" // x-release-please-version +const PackageVersion = "0.77.0" // x-release-please-version