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.11.4"
".": "0.11.5"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 51
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-8b5a722e4964d2d1dcdc34afccb6d742e1c927cbbd622264c8734f132e31a0f5.yml
openapi_spec_hash: ed101ff177c2e962653ca65acf939336
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-da8bfd5cfb5a6d9ccb7e4edd123b49284f4eccb32fc9b6fb7165548535122e12.yml
openapi_spec_hash: fd6ded34689331831b5c077f71b5f08f
config_hash: 49c2ff978aaa5ccb4ce324a72f116010
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## 0.11.5 (2025-09-29)

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

### Features

* Add App Version to Invocation and add filtering on App Version ([81f87e2](https://github.com/onkernel/kernel-go-sdk/commit/81f87e27ae242be9f7cfc75a6147e9eac669d4c4))
* Fix my incorrect grammer ([f04186f](https://github.com/onkernel/kernel-go-sdk/commit/f04186fd786d47e49c42028c0237e02fd08d03b1))


### Bug Fixes

* bugfix for setting JSON keys with special characters ([32304ba](https://github.com/onkernel/kernel-go-sdk/commit/32304baca3b01de677fd705da2b03787b56fdf35))

## 0.11.4 (2025-09-25)

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

<!-- x-release-please-end -->
Expand Down
14 changes: 7 additions & 7 deletions internal/apijson/encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import (

var encoders sync.Map // map[encoderEntry]encoderFunc

// If we want to set a literal key value into JSON using sjson, we need to make sure it doesn't have
// special characters that sjson interprets as a path.
var EscapeSJSONKey = strings.NewReplacer("\\", "\\\\", "|", "\\|", "#", "\\#", "@", "\\@", "*", "\\*", ".", "\\.", ":", "\\:", "?", "\\?").Replace

func Marshal(value any) ([]byte, error) {
e := &encoder{dateFormat: time.RFC3339}
return e.marshal(value)
Expand Down Expand Up @@ -270,7 +274,7 @@ func (e *encoder) newStructTypeEncoder(t reflect.Type) encoderFunc {
if encoded == nil {
continue
}
json, err = sjson.SetRawBytes(json, ef.tag.name, encoded)
json, err = sjson.SetRawBytes(json, EscapeSJSONKey(ef.tag.name), encoded)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -348,7 +352,7 @@ func (e *encoder) encodeMapEntries(json []byte, v reflect.Value) ([]byte, error)
}
encodedKeyString = string(encodedKeyBytes)
}
encodedKey := []byte(sjsonReplacer.Replace(encodedKeyString))
encodedKey := []byte(encodedKeyString)
pairs = append(pairs, mapPair{key: encodedKey, value: iter.Value()})
}

Expand All @@ -366,7 +370,7 @@ func (e *encoder) encodeMapEntries(json []byte, v reflect.Value) ([]byte, error)
if len(encodedValue) == 0 {
continue
}
json, err = sjson.SetRawBytes(json, string(p.key), encodedValue)
json, err = sjson.SetRawBytes(json, EscapeSJSONKey(string(p.key)), encodedValue)
if err != nil {
return nil, err
}
Expand All @@ -386,7 +390,3 @@ func (e *encoder) newMapEncoder(_ reflect.Type) encoderFunc {
return json, nil
}
}

// If we want to set a literal key value into JSON using sjson, we need to make sure it doesn't have
// special characters that sjson interprets as a path.
var sjsonReplacer *strings.Replacer = strings.NewReplacer(".", "\\.", ":", "\\:", "*", "\\*")
4 changes: 2 additions & 2 deletions internal/apijson/union.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func (d *decoderBuilder) newStructUnionDecoder(t reflect.Type) decoderFunc {

return func(n gjson.Result, v reflect.Value, state *decoderState) error {
if discriminated && n.Type == gjson.JSON && len(unionEntry.discriminatorKey) != 0 {
discriminator := n.Get(unionEntry.discriminatorKey).Value()
discriminator := n.Get(EscapeSJSONKey(unionEntry.discriminatorKey)).Value()
for _, decoder := range discriminatedDecoders {
if discriminator == decoder.discriminator {
inner := v.FieldByIndex(decoder.field.Index)
Expand Down Expand Up @@ -162,7 +162,7 @@ func (d *decoderBuilder) newUnionDecoder(t reflect.Type) decoderFunc {
}

if len(unionEntry.discriminatorKey) != 0 {
discriminatorValue := n.Get(unionEntry.discriminatorKey).Value()
discriminatorValue := n.Get(EscapeSJSONKey(unionEntry.discriminatorKey)).Value()
if discriminatorValue == variant.DiscriminatorValue {
inner := reflect.New(variant.Type).Elem()
err := decoder(n, inner, state)
Expand Down
2 changes: 1 addition & 1 deletion internal/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

package internal

const PackageVersion = "0.11.4" // x-release-please-version
const PackageVersion = "0.11.5" // x-release-please-version
18 changes: 16 additions & 2 deletions invocation.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ func (r *InvocationService) Get(ctx context.Context, id string, opts ...option.R
return
}

// Update an invocation's status or output. This can used to cancel an invocation
// by setting the status to "failed".
// Update an invocation's status or output. This can be used to cancel an
// invocation by setting the status to "failed".
func (r *InvocationService) Update(ctx context.Context, id string, body InvocationUpdateParams, opts ...option.RequestOption) (res *InvocationUpdateResponse, err error) {
opts = slices.Concat(r.Options, opts)
if id == "" {
Expand Down Expand Up @@ -169,6 +169,8 @@ type InvocationStateEventInvocation struct {
//
// Any of "queued", "running", "succeeded", "failed".
Status string `json:"status,required"`
// Version label for the application
Version string `json:"version,required"`
// RFC 3339 Nanoseconds timestamp when the invocation finished (null if still
// running)
FinishedAt time.Time `json:"finished_at,nullable" format:"date-time"`
Expand All @@ -186,6 +188,7 @@ type InvocationStateEventInvocation struct {
AppName respjson.Field
StartedAt respjson.Field
Status respjson.Field
Version respjson.Field
FinishedAt respjson.Field
Output respjson.Field
Payload respjson.Field
Expand Down Expand Up @@ -256,6 +259,8 @@ type InvocationGetResponse struct {
//
// Any of "queued", "running", "succeeded", "failed".
Status InvocationGetResponseStatus `json:"status,required"`
// Version label for the application
Version string `json:"version,required"`
// RFC 3339 Nanoseconds timestamp when the invocation finished (null if still
// running)
FinishedAt time.Time `json:"finished_at,nullable" format:"date-time"`
Expand All @@ -273,6 +278,7 @@ type InvocationGetResponse struct {
AppName respjson.Field
StartedAt respjson.Field
Status respjson.Field
Version respjson.Field
FinishedAt respjson.Field
Output respjson.Field
Payload respjson.Field
Expand Down Expand Up @@ -311,6 +317,8 @@ type InvocationUpdateResponse struct {
//
// Any of "queued", "running", "succeeded", "failed".
Status InvocationUpdateResponseStatus `json:"status,required"`
// Version label for the application
Version string `json:"version,required"`
// RFC 3339 Nanoseconds timestamp when the invocation finished (null if still
// running)
FinishedAt time.Time `json:"finished_at,nullable" format:"date-time"`
Expand All @@ -328,6 +336,7 @@ type InvocationUpdateResponse struct {
AppName respjson.Field
StartedAt respjson.Field
Status respjson.Field
Version respjson.Field
FinishedAt respjson.Field
Output respjson.Field
Payload respjson.Field
Expand Down Expand Up @@ -366,6 +375,8 @@ type InvocationListResponse struct {
//
// Any of "queued", "running", "succeeded", "failed".
Status InvocationListResponseStatus `json:"status,required"`
// Version label for the application
Version string `json:"version,required"`
// RFC 3339 Nanoseconds timestamp when the invocation finished (null if still
// running)
FinishedAt time.Time `json:"finished_at,nullable" format:"date-time"`
Expand All @@ -383,6 +394,7 @@ type InvocationListResponse struct {
AppName respjson.Field
StartedAt respjson.Field
Status respjson.Field
Version respjson.Field
FinishedAt respjson.Field
Output respjson.Field
Payload respjson.Field
Expand Down Expand Up @@ -558,6 +570,8 @@ type InvocationListParams struct {
// Show invocations that have started since the given time (RFC timestamps or
// durations like 5m).
Since param.Opt[string] `query:"since,omitzero" json:"-"`
// Filter results by application version.
Version param.Opt[string] `query:"version,omitzero" json:"-"`
// Filter results by invocation status.
//
// Any of "queued", "running", "succeeded", "failed".
Expand Down
1 change: 1 addition & 0 deletions invocation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ func TestInvocationListWithOptionalParams(t *testing.T) {
Offset: kernel.Int(0),
Since: kernel.String("2025-06-20T12:00:00Z"),
Status: kernel.InvocationListParamsStatusQueued,
Version: kernel.String("version"),
})
if err != nil {
var apierr *kernel.Error
Expand Down
7 changes: 6 additions & 1 deletion packages/param/encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"reflect"
"strings"
"time"

shimjson "github.com/onkernel/kernel-go-sdk/internal/encoding/json"
Expand All @@ -14,6 +15,10 @@ import (
// EncodedAsDate is not be stable and shouldn't be relied upon
type EncodedAsDate Opt[time.Time]

// If we want to set a literal key value into JSON using sjson, we need to make sure it doesn't have
// special characters that sjson interprets as a path.
var EscapeSJSONKey = strings.NewReplacer("\\", "\\\\", "|", "\\|", "#", "\\#", "@", "\\@", "*", "\\*", ".", "\\.", ":", "\\:", "?", "\\?").Replace

type forceOmit int

func (m EncodedAsDate) MarshalJSON() ([]byte, error) {
Expand Down Expand Up @@ -52,7 +57,7 @@ func MarshalWithExtras[T ParamStruct, R any](f T, underlying any, extras map[str
}
continue
}
bytes, err = sjson.SetBytes(bytes, k, v)
bytes, err = sjson.SetBytes(bytes, EscapeSJSONKey(k), v)
if err != nil {
return nil, err
}
Expand Down