Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.111.0"
".": "0.112.0"
}
2 changes: 1 addition & 1 deletion .stats.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
configured_endpoints: 169
configured_endpoints: 172
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Changelog

## [0.112.0](https://github.com/kernel/kernel-go-sdk/compare/v0.111.0...v0.112.0) (2026-09-24)


### Features

* Add profiles to browser pool acquire ([b50814f](https://github.com/kernel/kernel-go-sdk/commit/b50814fd0cd8cff8a37e56b48142eef0b3653b7c))
* Correct monitor_disconnected description on computed state ([0584ea1](https://github.com/kernel/kernel-go-sdk/commit/0584ea1d2238bfb06f1995ef4cab305917941efa))
* Expose Search rollout access in org entitlements ([8e055e1](https://github.com/kernel/kernel-go-sdk/commit/8e055e16e1db7872b2bb298901c760aba435030d))
* Filter archived telemetry events by type ([a9ee57c](https://github.com/kernel/kernel-go-sdk/commit/a9ee57caab330fac08e26e24896274baf2e64b43))
* Proxy custom WebMCP tools in the control plane ([47c1310](https://github.com/kernel/kernel-go-sdk/commit/47c13103242727ad8633062d359aee2ad7d6cb32))
* Publish iframe and worker browser target types ([1ef7b7c](https://github.com/kernel/kernel-go-sdk/commit/1ef7b7c34dc3b987d6c515c82ea399c424f0c6e6))
* Route browser destinations through selected proxies ([ffc38db](https://github.com/kernel/kernel-go-sdk/commit/ffc38db98feff227e904bd3c84e11cc715c010a8))

## [0.111.0](https://github.com/kernel/kernel-go-sdk/compare/v0.110.0...v0.111.0) (2026-09-22)


Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Or to pin the version:
<!-- x-release-please-start-version -->

```sh
go get -u 'github.com/kernel/kernel-go-sdk@v0.111.0'
go get -u 'github.com/kernel/kernel-go-sdk@v0.112.0'
```

<!-- x-release-please-end -->
Expand Down
22 changes: 21 additions & 1 deletion api.md
Original file line number Diff line number Diff line change
Expand Up @@ -333,17 +333,37 @@ Params Types:

Response Types:

- <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#CustomToolSource">CustomToolSource</a>
- <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#InvocationResult">InvocationResult</a>
- <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#Tool">Tool</a>
- <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#ToolAnnotations">ToolAnnotations</a>
- <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#ToolFrame">ToolFrame</a>
- <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#ToolMetadata">ToolMetadata</a>
- <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#ToolSource">ToolSource</a>
- <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#ToolsResponse">ToolsResponse</a>

Methods:

- <code title="post /browsers/{id_or_name}/webmcp/invoke">client.Browsers.Webmcp.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserWebmcpService.InvokeTool">InvokeTool</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, idOrName <a href="https://pkg.go.dev/builtin#string">string</a>, body <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserWebmcpInvokeToolParams">BrowserWebmcpInvokeToolParams</a>) (\*<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#InvocationResult">InvocationResult</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="get /browsers/{id_or_name}/webmcp/tools">client.Browsers.Webmcp.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserWebmcpService.ListTools">ListTools</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, idOrName <a href="https://pkg.go.dev/builtin#string">string</a>) (\*<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#ToolsResponse">ToolsResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="get /browsers/{id_or_name}/webmcp/tools">client.Browsers.Webmcp.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserWebmcpService.ListTools">ListTools</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, idOrName <a href="https://pkg.go.dev/builtin#string">string</a>, query <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserWebmcpListToolsParams">BrowserWebmcpListToolsParams</a>) (\*<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#ToolsResponse">ToolsResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>

### CustomTools

Params Types:

- <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#AddRequestParam">AddRequestParam</a>

Response Types:

- <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#CustomToolsResponse">CustomToolsResponse</a>
- <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#Definition">Definition</a>
- <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#Match">Match</a>

Methods:

- <code title="get /browsers/{id_or_name}/webmcp/custom-tools">client.Browsers.Webmcp.CustomTools.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserWebmcpCustomToolService.List">List</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, idOrName <a href="https://pkg.go.dev/builtin#string">string</a>) (\*<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#CustomToolsResponse">CustomToolsResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="post /browsers/{id_or_name}/webmcp/custom-tools">client.Browsers.Webmcp.CustomTools.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserWebmcpCustomToolService.Add">Add</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, idOrName <a href="https://pkg.go.dev/builtin#string">string</a>, body <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserWebmcpCustomToolAddParams">BrowserWebmcpCustomToolAddParams</a>) (\*<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#CustomToolsResponse">CustomToolsResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="delete /browsers/{id_or_name}/webmcp/custom-tools/{id}">client.Browsers.Webmcp.CustomTools.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserWebmcpCustomToolService.Remove">Remove</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>, body <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#BrowserWebmcpCustomToolRemoveParams">BrowserWebmcpCustomToolRemoveParams</a>) <a href="https://pkg.go.dev/builtin#error">error</a></code>

# Profiles

Expand Down
108 changes: 108 additions & 0 deletions browser.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,25 @@ type BrowserNetworkConfig struct {
// destinations. Not related to a proxy's bypass_hosts, which selects between
// upstream-proxy and Kernel-managed direct egress and cannot reach into a VPN.
PrivateHosts []string `json:"private_hosts"`
// Per-destination proxy routes for a browser session. After setup, a destination
// hostname is matched against every route's hosts, regardless of port; route order
// does not matter. An exact hostname beats a wildcard, and a longer wildcard
// suffix beats a shorter one (for a.b.example.com: "a.b.example.com" >
// "_.b.example.com" > "_.example.com"). A host pattern may appear in only one
// route. "\*.example.com" matches subdomains only, not example.com. A matched
// request selects the route's proxy instead of the session's top-level proxy
// (including mode: direct); the route proxy's own bypass_hosts still apply. If the
// route proxy becomes unavailable, matched requests fail closed without falling
// back. Requests that match no route use the session's default egress from the
// top-level proxy field (or the browser default when proxy is omitted: stealth
// proxy or direct egress). Routes take effect once the session is created;
// start_url and other traffic during browser setup use the top-level proxy.
// Setting routes requires proxy v3. Not supported on browser pools.
ProxyRoutes []BrowserNetworkConfigProxyRoute `json:"proxy_routes"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
PrivateHosts respjson.Field
ProxyRoutes respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
Expand All @@ -260,6 +276,48 @@ func (r BrowserNetworkConfig) ToParam() BrowserNetworkConfigParam {
return param.Override[BrowserNetworkConfigParam](json.RawMessage(r.RawJSON()))
}

type BrowserNetworkConfigProxyRoute struct {
// Exact hostnames or leading \*. wildcard patterns (subdomains only); patterns
// cannot include ports, and matching ignores the destination port. Hosts not
// matched by any route use the session's top-level proxy (or the browser default
// when proxy is omitted).
Hosts []string `json:"hosts" api:"required"`
// Select an active non-direct proxy by ID or name. Responses always use ID.
Proxy BrowserNetworkConfigProxyRouteProxy `json:"proxy" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Hosts respjson.Field
Proxy respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
}

// Returns the unmodified JSON received from the API
func (r BrowserNetworkConfigProxyRoute) RawJSON() string { return r.JSON.raw }
func (r *BrowserNetworkConfigProxyRoute) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}

// Select an active non-direct proxy by ID or name. Responses always use ID.
type BrowserNetworkConfigProxyRouteProxy struct {
ID string `json:"id"`
Name string `json:"name"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
ID respjson.Field
Name respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
}

// Returns the unmodified JSON received from the API
func (r BrowserNetworkConfigProxyRouteProxy) RawJSON() string { return r.JSON.raw }
func (r *BrowserNetworkConfigProxyRouteProxy) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}

// Network configuration for a browser session or browser pool.
type BrowserNetworkConfigParam struct {
// Destinations the browser reaches directly through the session's own network
Expand All @@ -285,6 +343,21 @@ type BrowserNetworkConfigParam struct {
// destinations. Not related to a proxy's bypass_hosts, which selects between
// upstream-proxy and Kernel-managed direct egress and cannot reach into a VPN.
PrivateHosts []string `json:"private_hosts,omitzero"`
// Per-destination proxy routes for a browser session. After setup, a destination
// hostname is matched against every route's hosts, regardless of port; route order
// does not matter. An exact hostname beats a wildcard, and a longer wildcard
// suffix beats a shorter one (for a.b.example.com: "a.b.example.com" >
// "_.b.example.com" > "_.example.com"). A host pattern may appear in only one
// route. "\*.example.com" matches subdomains only, not example.com. A matched
// request selects the route's proxy instead of the session's top-level proxy
// (including mode: direct); the route proxy's own bypass_hosts still apply. If the
// route proxy becomes unavailable, matched requests fail closed without falling
// back. Requests that match no route use the session's default egress from the
// top-level proxy field (or the browser default when proxy is omitted: stealth
// proxy or direct egress). Routes take effect once the session is created;
// start_url and other traffic during browser setup use the top-level proxy.
// Setting routes requires proxy v3. Not supported on browser pools.
ProxyRoutes []BrowserNetworkConfigProxyRouteParam `json:"proxy_routes,omitzero"`
paramObj
}

Expand All @@ -296,6 +369,41 @@ func (r *BrowserNetworkConfigParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}

// The properties Hosts, Proxy are required.
type BrowserNetworkConfigProxyRouteParam struct {
// Exact hostnames or leading \*. wildcard patterns (subdomains only); patterns
// cannot include ports, and matching ignores the destination port. Hosts not
// matched by any route use the session's top-level proxy (or the browser default
// when proxy is omitted).
Hosts []string `json:"hosts,omitzero" api:"required"`
// Select an active non-direct proxy by ID or name. Responses always use ID.
Proxy BrowserNetworkConfigProxyRouteProxyParam `json:"proxy,omitzero" api:"required"`
paramObj
}

func (r BrowserNetworkConfigProxyRouteParam) MarshalJSON() (data []byte, err error) {
type shadow BrowserNetworkConfigProxyRouteParam
return param.MarshalObject(r, (*shadow)(&r))
}
func (r *BrowserNetworkConfigProxyRouteParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}

// Select an active non-direct proxy by ID or name. Responses always use ID.
type BrowserNetworkConfigProxyRouteProxyParam struct {
ID param.Opt[string] `json:"id,omitzero"`
Name param.Opt[string] `json:"name,omitzero"`
paramObj
}

func (r BrowserNetworkConfigProxyRouteProxyParam) MarshalJSON() (data []byte, err error) {
type shadow BrowserNetworkConfigProxyRouteProxyParam
return param.MarshalObject(r, (*shadow)(&r))
}
func (r *BrowserNetworkConfigProxyRouteProxyParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}

// Browser pool this session was acquired from, if any.
type BrowserPoolRef struct {
// Browser pool ID
Expand Down
7 changes: 7 additions & 0 deletions browser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ func TestBrowserNewWithOptionalParams(t *testing.T) {
Name: kernel.String("checkout-flow-1"),
Network: kernel.BrowserNetworkConfigParam{
PrivateHosts: []string{"*.example.ts.net", "100.64.0.0/10"},
ProxyRoutes: []kernel.BrowserNetworkConfigProxyRouteParam{{
Hosts: []string{"string"},
Proxy: kernel.BrowserNetworkConfigProxyRouteProxyParam{
ID: kernel.String("x"),
Name: kernel.String("x"),
},
}},
},
Profile: shared.BrowserProfileParam{
ID: kernel.String("id"),
Expand Down
7 changes: 6 additions & 1 deletion browserpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,10 @@ type BrowserPoolAcquireParams struct {
// is reset to the pool's baseline, so the override does not carry over to the next
// lease.
Telemetry BrowserPoolAcquireParamsTelemetry `json:"telemetry,omitzero"`
// Profile selection for the browser session. Provide either id or name. If
// specified, the matching profile will be loaded into the browser session.
// Profiles must be created beforehand.
Profile shared.BrowserProfileParam `json:"profile,omitzero"`
// Optional user-defined key-value tags for the acquired browser session, used to
// find and group sessions later. Applies to this lease only and are cleared when
// the browser is released back to the pool. Up to 50 pairs.
Expand Down Expand Up @@ -1112,7 +1116,8 @@ type BrowserPoolReleaseParams struct {
// Defaults to true. A reused browser keeps the configuration it was created with,
// so it does not pick up pool configuration changes made while it was in use.
// Release with `reuse: false`, or flush the pool afterward, to rebuild it with the
// current configuration.
// current configuration. Browsers loaded with an acquire-time profile are always
// destroyed and replaced, even when reuse is true.
Reuse param.Opt[bool] `json:"reuse,omitzero"`
paramObj
}
Expand Down
21 changes: 20 additions & 1 deletion browserpool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ func TestBrowserPoolNewWithOptionalParams(t *testing.T) {
Name: kernel.String("my-pool"),
Network: kernel.BrowserNetworkConfigParam{
PrivateHosts: []string{"*.example.ts.net", "100.64.0.0/10"},
ProxyRoutes: []kernel.BrowserNetworkConfigProxyRouteParam{{
Hosts: []string{"string"},
Proxy: kernel.BrowserNetworkConfigProxyRouteProxyParam{
ID: kernel.String("x"),
Name: kernel.String("x"),
},
}},
},
Profile: kernel.BrowserPoolNewParamsProfile{
ID: kernel.String("id"),
Expand Down Expand Up @@ -169,6 +176,13 @@ func TestBrowserPoolUpdateWithOptionalParams(t *testing.T) {
Name: kernel.String("my-pool"),
Network: kernel.BrowserNetworkConfigParam{
PrivateHosts: []string{"*.example.ts.net", "100.64.0.0/10"},
ProxyRoutes: []kernel.BrowserNetworkConfigProxyRouteParam{{
Hosts: []string{"string"},
Proxy: kernel.BrowserNetworkConfigProxyRouteProxyParam{
ID: kernel.String("x"),
Name: kernel.String("x"),
},
}},
},
Profile: kernel.BrowserPoolUpdateParamsProfile{
ID: kernel.String("id"),
Expand Down Expand Up @@ -320,7 +334,12 @@ func TestBrowserPoolAcquireWithOptionalParams(t *testing.T) {
kernel.BrowserPoolAcquireParams{
AcquireTimeoutSeconds: kernel.Int(0),
Name: kernel.String("checkout-flow-1"),
StartURL: kernel.String("https://example.com"),
Profile: shared.BrowserProfileParam{
ID: kernel.String("id"),
Name: kernel.String("name"),
SaveChanges: kernel.Bool(true),
},
StartURL: kernel.String("https://example.com"),
Tags: kernel.Tags{
"team": "backend",
"env": "staging",
Expand Down
Loading
Loading