Skip to content
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.22.0"
".": "0.23.0"
}
8 changes: 4 additions & 4 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 80
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-8a37652fa586b8932466d16285359a89988505f850787f8257d0c4c7053da173.yml
openapi_spec_hash: 042765a113f6d08109e8146b302323ec
config_hash: 113f1e5bc3567628a5d51c70bc00969d
configured_endpoints: 82
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-dac11bdb857e700a8c39d183e753ddd1ebaaca69fd9fc5ee57d6b56b70b00e6e.yml
openapi_spec_hash: 78fbc50dd0b61cdc87564fbea278ee23
config_hash: a4b4d14bdf6af723b235a6981977627c
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
# Changelog

## 0.23.0 (2025-12-16)

Full Changelog: [v0.22.0...v0.23.0](https://github.com/onkernel/kernel-go-sdk/compare/v0.22.0...v0.23.0)

### Features

* **encoder:** support bracket encoding form-data object members ([7d11b85](https://github.com/onkernel/kernel-go-sdk/commit/7d11b85f517bfa5875440c516de735009fbd05a0))
* enhance agent authentication API with new endpoints and request… ([7f2d67a](https://github.com/onkernel/kernel-go-sdk/commit/7f2d67aeba880e8d35b084ffa6f0c2364f88378a))
* Enhance AuthAgent model with last_auth_check_at field ([a3cb1e1](https://github.com/onkernel/kernel-go-sdk/commit/a3cb1e13b7700f1ccce3393411a08f822e216d1f))


### Bug Fixes

* **client:** copy over change to params names to ExecuteNewRequeest ([92fd6c1](https://github.com/onkernel/kernel-go-sdk/commit/92fd6c10cb2c451f9381d3969c2aa80b121addfe))
* **mcp:** correct code tool API endpoint ([563016a](https://github.com/onkernel/kernel-go-sdk/commit/563016aabd8010af7bf2d1db0b7436f31b0fd23e))
* rename param to avoid collision ([a20c158](https://github.com/onkernel/kernel-go-sdk/commit/a20c1588a19c48cfa6503af80c0ba6ad4add76f7))


### Chores

* elide duplicate aliases ([9eb4ec3](https://github.com/onkernel/kernel-go-sdk/commit/9eb4ec3048ab55e534e84de255ca0f2d22d5f233))
* **internal:** codegen related update ([839598d](https://github.com/onkernel/kernel-go-sdk/commit/839598d5a188b64afe16e1df16915c94f822b309))

## 0.22.0 (2025-12-06)

Full Changelog: [v0.21.0...v0.22.0](https://github.com/onkernel/kernel-go-sdk/compare/v0.21.0...v0.22.0)
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/onkernel/kernel-go-sdk@v0.22.0'
go get -u 'github.com/onkernel/kernel-go-sdk@v0.23.0'
```

<!-- x-release-please-end -->
Expand Down
220 changes: 150 additions & 70 deletions agentauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@ package kernel

import (
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
"net/url"
"slices"
"time"

"github.com/onkernel/kernel-go-sdk/internal/apijson"
"github.com/onkernel/kernel-go-sdk/internal/apiquery"
shimjson "github.com/onkernel/kernel-go-sdk/internal/encoding/json"
"github.com/onkernel/kernel-go-sdk/internal/requestconfig"
"github.com/onkernel/kernel-go-sdk/option"
"github.com/onkernel/kernel-go-sdk/packages/pagination"
"github.com/onkernel/kernel-go-sdk/packages/param"
"github.com/onkernel/kernel-go-sdk/packages/respjson"
)
Expand All @@ -38,6 +43,17 @@ func NewAgentAuthService(opts ...option.RequestOption) (r AgentAuthService) {
return
}

// Creates a new auth agent for the specified domain and profile combination, or
// returns an existing one if it already exists. This is idempotent - calling with
// the same domain and profile will return the same agent. Does NOT start an
// invocation - use POST /agents/auth/invocations to start an auth flow.
func (r *AgentAuthService) New(ctx context.Context, body AgentAuthNewParams, opts ...option.RequestOption) (res *AuthAgent, err error) {
opts = slices.Concat(r.Options, opts)
path := "agents/auth"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
return
}

// Retrieve an auth agent by its ID. Returns the current authentication status of
// the managed profile.
func (r *AgentAuthService) Get(ctx context.Context, id string, opts ...option.RequestOption) (res *AuthAgent, err error) {
Expand All @@ -51,14 +67,27 @@ func (r *AgentAuthService) Get(ctx context.Context, id string, opts ...option.Re
return
}

// Creates a browser session and returns a handoff code for the hosted flow. Uses
// standard API key or JWT authentication (not the JWT returned by the exchange
// endpoint).
func (r *AgentAuthService) Start(ctx context.Context, body AgentAuthStartParams, opts ...option.RequestOption) (res *AgentAuthStartResponse, err error) {
// List auth agents with optional filters for profile_name and target_domain.
func (r *AgentAuthService) List(ctx context.Context, query AgentAuthListParams, opts ...option.RequestOption) (res *pagination.OffsetPagination[AuthAgent], err error) {
var raw *http.Response
opts = slices.Concat(r.Options, opts)
path := "agents/auth/start"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
return
opts = append([]option.RequestOption{option.WithResponseInto(&raw)}, opts...)
path := "agents/auth"
cfg, err := requestconfig.NewRequestConfig(ctx, http.MethodGet, path, query, &res, opts...)
if err != nil {
return nil, err
}
err = cfg.Execute()
if err != nil {
return nil, err
}
res.SetPageConfig(cfg, raw)
return res, nil
}

// List auth agents with optional filters for profile_name and target_domain.
func (r *AgentAuthService) ListAutoPaging(ctx context.Context, query AgentAuthListParams, opts ...option.RequestOption) *pagination.OffsetPaginationAutoPager[AuthAgent] {
return pagination.NewOffsetPaginationAutoPager(r.List(ctx, query, opts...))
}

// Response from discover endpoint matching AuthBlueprint schema
Expand Down Expand Up @@ -133,36 +162,6 @@ const (
AgentAuthInvocationResponseStatusCanceled AgentAuthInvocationResponseStatus = "CANCELED"
)

// Response from starting an agent authentication invocation
type AgentAuthStartResponse struct {
// Unique identifier for the auth agent managing this domain/profile
AuthAgentID string `json:"auth_agent_id,required"`
// When the handoff code expires
ExpiresAt time.Time `json:"expires_at,required" format:"date-time"`
// One-time code for handoff
HandoffCode string `json:"handoff_code,required"`
// URL to redirect user to
HostedURL string `json:"hosted_url,required" format:"uri"`
// Unique identifier for the invocation
InvocationID string `json:"invocation_id,required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
AuthAgentID respjson.Field
ExpiresAt respjson.Field
HandoffCode respjson.Field
HostedURL respjson.Field
InvocationID respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
}

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

// Response from submit endpoint matching SubmitResult schema
type AgentAuthSubmitResponse struct {
// Whether submission succeeded
Expand Down Expand Up @@ -213,14 +212,17 @@ type AuthAgent struct {
//
// Any of "AUTHENTICATED", "NEEDS_AUTH".
Status AuthAgentStatus `json:"status,required"`
// When the last authentication check was performed
LastAuthCheckAt time.Time `json:"last_auth_check_at" format:"date-time"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
ID respjson.Field
Domain respjson.Field
ProfileName respjson.Field
Status respjson.Field
ExtraFields map[string]respjson.Field
raw string
ID respjson.Field
Domain respjson.Field
ProfileName respjson.Field
Status respjson.Field
LastAuthCheckAt respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
}

Expand All @@ -238,6 +240,89 @@ const (
AuthAgentStatusNeedsAuth AuthAgentStatus = "NEEDS_AUTH"
)

// Request to create or find an auth agent
//
// The properties ProfileName, TargetDomain are required.
type AuthAgentCreateRequestParam struct {
// Name of the profile to use for this auth agent
ProfileName string `json:"profile_name,required"`
// Target domain for authentication
TargetDomain string `json:"target_domain,required"`
// Optional login page URL. If provided, will be stored on the agent and used to
// skip discovery in future invocations.
LoginURL param.Opt[string] `json:"login_url,omitzero" format:"uri"`
// Optional proxy configuration
Proxy AuthAgentCreateRequestProxyParam `json:"proxy,omitzero"`
paramObj
}

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

// Optional proxy configuration
type AuthAgentCreateRequestProxyParam struct {
// ID of the proxy to use
ProxyID param.Opt[string] `json:"proxy_id,omitzero"`
paramObj
}

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

// Request to create an invocation for an existing auth agent
//
// The property AuthAgentID is required.
type AuthAgentInvocationCreateRequestParam struct {
// ID of the auth agent to create an invocation for
AuthAgentID string `json:"auth_agent_id,required"`
paramObj
}

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

// Response from creating an auth agent invocation
type AuthAgentInvocationCreateResponse struct {
// When the handoff code expires
ExpiresAt time.Time `json:"expires_at,required" format:"date-time"`
// One-time code for handoff
HandoffCode string `json:"handoff_code,required"`
// URL to redirect user to
HostedURL string `json:"hosted_url,required" format:"uri"`
// Unique identifier for the invocation
InvocationID string `json:"invocation_id,required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
ExpiresAt respjson.Field
HandoffCode respjson.Field
HostedURL respjson.Field
InvocationID respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
}

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

// A discovered form field
type DiscoveredField struct {
// Field label
Expand Down Expand Up @@ -286,40 +371,35 @@ const (
DiscoveredFieldTypeCode DiscoveredFieldType = "code"
)

type AgentAuthStartParams struct {
// Name of the profile to use for this flow
ProfileName string `json:"profile_name,required"`
// Target domain for authentication
TargetDomain string `json:"target_domain,required"`
// Optional logo URL for the application
AppLogoURL param.Opt[string] `json:"app_logo_url,omitzero" format:"uri"`
// Optional login page URL. If provided, will be stored on the agent and used to
// skip Phase 1 discovery in future invocations.
LoginURL param.Opt[string] `json:"login_url,omitzero" format:"uri"`
// Optional proxy configuration
Proxy AgentAuthStartParamsProxy `json:"proxy,omitzero"`
type AgentAuthNewParams struct {
// Request to create or find an auth agent
AuthAgentCreateRequest AuthAgentCreateRequestParam
paramObj
}

func (r AgentAuthStartParams) MarshalJSON() (data []byte, err error) {
type shadow AgentAuthStartParams
return param.MarshalObject(r, (*shadow)(&r))
func (r AgentAuthNewParams) MarshalJSON() (data []byte, err error) {
return shimjson.Marshal(r.AuthAgentCreateRequest)
}
func (r *AgentAuthStartParams) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
func (r *AgentAuthNewParams) UnmarshalJSON(data []byte) error {
return json.Unmarshal(data, &r.AuthAgentCreateRequest)
}

// Optional proxy configuration
type AgentAuthStartParamsProxy struct {
// ID of the proxy to use
ProxyID param.Opt[string] `json:"proxy_id,omitzero"`
type AgentAuthListParams struct {
// Maximum number of results to return
Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
// Number of results to skip
Offset param.Opt[int64] `query:"offset,omitzero" json:"-"`
// Filter by profile name
ProfileName param.Opt[string] `query:"profile_name,omitzero" json:"-"`
// Filter by target domain
TargetDomain param.Opt[string] `query:"target_domain,omitzero" json:"-"`
paramObj
}

func (r AgentAuthStartParamsProxy) MarshalJSON() (data []byte, err error) {
type shadow AgentAuthStartParamsProxy
return param.MarshalObject(r, (*shadow)(&r))
}
func (r *AgentAuthStartParamsProxy) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
// URLQuery serializes [AgentAuthListParams]'s query parameters as `url.Values`.
func (r AgentAuthListParams) URLQuery() (v url.Values, err error) {
return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{
ArrayFormat: apiquery.ArrayQueryFormatComma,
NestedFormat: apiquery.NestedQueryFormatBrackets,
})
}
Loading