@@ -5,16 +5,22 @@ package kernel
55import (
66 "bytes"
77 "context"
8+ "encoding/json"
9+ "errors"
10+ "fmt"
811 "io"
912 "mime/multipart"
1013 "net/http"
14+ "time"
1115
1216 "github.com/onkernel/kernel-go-sdk/internal/apiform"
1317 "github.com/onkernel/kernel-go-sdk/internal/apijson"
1418 "github.com/onkernel/kernel-go-sdk/internal/requestconfig"
1519 "github.com/onkernel/kernel-go-sdk/option"
1620 "github.com/onkernel/kernel-go-sdk/packages/param"
1721 "github.com/onkernel/kernel-go-sdk/packages/respjson"
22+ "github.com/onkernel/kernel-go-sdk/packages/ssestream"
23+ "github.com/onkernel/kernel-go-sdk/shared/constant"
1824)
1925
2026// AppDeploymentService contains methods and other services that help with
@@ -44,6 +50,25 @@ func (r *AppDeploymentService) New(ctx context.Context, body AppDeploymentNewPar
4450 return
4551}
4652
53+ // Establishes a Server-Sent Events (SSE) stream that delivers real-time logs and
54+ // status updates for a deployed application. The stream terminates automatically
55+ // once the application reaches a terminal state.
56+ func (r * AppDeploymentService ) FollowStreaming (ctx context.Context , id string , opts ... option.RequestOption ) (stream * ssestream.Stream [[]AppDeploymentFollowResponseUnion ]) {
57+ var (
58+ raw * http.Response
59+ err error
60+ )
61+ opts = append (r .Options [:], opts ... )
62+ opts = append ([]option.RequestOption {option .WithHeader ("Accept" , "text/event-stream" )}, opts ... )
63+ if id == "" {
64+ err = errors .New ("missing required id parameter" )
65+ return
66+ }
67+ path := fmt .Sprintf ("apps/%s/events" , id )
68+ err = requestconfig .ExecuteNewRequest (ctx , http .MethodGet , path , nil , & raw , opts ... )
69+ return ssestream .NewStream [[]AppDeploymentFollowResponseUnion ](ssestream .NewDecoder (raw ), err )
70+ }
71+
4772type AppDeploymentNewResponse struct {
4873 // List of apps deployed
4974 Apps []AppDeploymentNewResponseApp `json:"apps,required"`
@@ -119,6 +144,156 @@ const (
119144 AppDeploymentNewResponseStatusFailed AppDeploymentNewResponseStatus = "failed"
120145)
121146
147+ // AppDeploymentFollowResponseUnion contains all possible properties and values
148+ // from [AppDeploymentFollowResponseState],
149+ // [AppDeploymentFollowResponseStateUpdate], [AppDeploymentFollowResponseLog].
150+ //
151+ // Use the [AppDeploymentFollowResponseUnion.AsAny] method to switch on the
152+ // variant.
153+ //
154+ // Use the methods beginning with 'As' to cast the union to one of its variants.
155+ type AppDeploymentFollowResponseUnion struct {
156+ // Any of "state", "state_update", "log".
157+ Event string `json:"event"`
158+ State string `json:"state"`
159+ Timestamp time.Time `json:"timestamp"`
160+ // This field is from variant [AppDeploymentFollowResponseLog].
161+ Message string `json:"message"`
162+ JSON struct {
163+ Event respjson.Field
164+ State respjson.Field
165+ Timestamp respjson.Field
166+ Message respjson.Field
167+ raw string
168+ } `json:"-"`
169+ }
170+
171+ // anyAppDeploymentFollowResponse is implemented by each variant of
172+ // [AppDeploymentFollowResponseUnion] to add type safety for the return type of
173+ // [AppDeploymentFollowResponseUnion.AsAny]
174+ type anyAppDeploymentFollowResponse interface {
175+ implAppDeploymentFollowResponseUnion ()
176+ }
177+
178+ func (AppDeploymentFollowResponseState ) implAppDeploymentFollowResponseUnion () {}
179+ func (AppDeploymentFollowResponseStateUpdate ) implAppDeploymentFollowResponseUnion () {}
180+ func (AppDeploymentFollowResponseLog ) implAppDeploymentFollowResponseUnion () {}
181+
182+ // Use the following switch statement to find the correct variant
183+ //
184+ // switch variant := AppDeploymentFollowResponseUnion.AsAny().(type) {
185+ // case kernel.AppDeploymentFollowResponseState:
186+ // case kernel.AppDeploymentFollowResponseStateUpdate:
187+ // case kernel.AppDeploymentFollowResponseLog:
188+ // default:
189+ // fmt.Errorf("no variant present")
190+ // }
191+ func (u AppDeploymentFollowResponseUnion ) AsAny () anyAppDeploymentFollowResponse {
192+ switch u .Event {
193+ case "state" :
194+ return u .AsState ()
195+ case "state_update" :
196+ return u .AsStateUpdate ()
197+ case "log" :
198+ return u .AsLog ()
199+ }
200+ return nil
201+ }
202+
203+ func (u AppDeploymentFollowResponseUnion ) AsState () (v AppDeploymentFollowResponseState ) {
204+ apijson .UnmarshalRoot (json .RawMessage (u .JSON .raw ), & v )
205+ return
206+ }
207+
208+ func (u AppDeploymentFollowResponseUnion ) AsStateUpdate () (v AppDeploymentFollowResponseStateUpdate ) {
209+ apijson .UnmarshalRoot (json .RawMessage (u .JSON .raw ), & v )
210+ return
211+ }
212+
213+ func (u AppDeploymentFollowResponseUnion ) AsLog () (v AppDeploymentFollowResponseLog ) {
214+ apijson .UnmarshalRoot (json .RawMessage (u .JSON .raw ), & v )
215+ return
216+ }
217+
218+ // Returns the unmodified JSON received from the API
219+ func (u AppDeploymentFollowResponseUnion ) RawJSON () string { return u .JSON .raw }
220+
221+ func (r * AppDeploymentFollowResponseUnion ) UnmarshalJSON (data []byte ) error {
222+ return apijson .UnmarshalRoot (data , r )
223+ }
224+
225+ // Initial state of the application, emitted once when subscribing.
226+ type AppDeploymentFollowResponseState struct {
227+ // Event type identifier (always "state").
228+ Event constant.State `json:"event,required"`
229+ // Current application state (e.g., "deploying", "running", "succeeded", "failed").
230+ State string `json:"state,required"`
231+ // Time the state was reported.
232+ Timestamp time.Time `json:"timestamp" format:"date-time"`
233+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
234+ JSON struct {
235+ Event respjson.Field
236+ State respjson.Field
237+ Timestamp respjson.Field
238+ ExtraFields map [string ]respjson.Field
239+ raw string
240+ } `json:"-"`
241+ }
242+
243+ // Returns the unmodified JSON received from the API
244+ func (r AppDeploymentFollowResponseState ) RawJSON () string { return r .JSON .raw }
245+ func (r * AppDeploymentFollowResponseState ) UnmarshalJSON (data []byte ) error {
246+ return apijson .UnmarshalRoot (data , r )
247+ }
248+
249+ // An update emitted when the application's state changes.
250+ type AppDeploymentFollowResponseStateUpdate struct {
251+ // Event type identifier (always "state_update").
252+ Event constant.StateUpdate `json:"event,required"`
253+ // New application state (e.g., "running", "succeeded", "failed").
254+ State string `json:"state,required"`
255+ // Time the state change occurred.
256+ Timestamp time.Time `json:"timestamp" format:"date-time"`
257+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
258+ JSON struct {
259+ Event respjson.Field
260+ State respjson.Field
261+ Timestamp respjson.Field
262+ ExtraFields map [string ]respjson.Field
263+ raw string
264+ } `json:"-"`
265+ }
266+
267+ // Returns the unmodified JSON received from the API
268+ func (r AppDeploymentFollowResponseStateUpdate ) RawJSON () string { return r .JSON .raw }
269+ func (r * AppDeploymentFollowResponseStateUpdate ) UnmarshalJSON (data []byte ) error {
270+ return apijson .UnmarshalRoot (data , r )
271+ }
272+
273+ // A log entry from the application.
274+ type AppDeploymentFollowResponseLog struct {
275+ // Event type identifier (always "log").
276+ Event constant.Log `json:"event,required"`
277+ // Log message text.
278+ Message string `json:"message,required"`
279+ // Time the log entry was produced.
280+ Timestamp time.Time `json:"timestamp" format:"date-time"`
281+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
282+ JSON struct {
283+ Event respjson.Field
284+ Message respjson.Field
285+ Timestamp respjson.Field
286+ ExtraFields map [string ]respjson.Field
287+ raw string
288+ } `json:"-"`
289+ }
290+
291+ // Returns the unmodified JSON received from the API
292+ func (r AppDeploymentFollowResponseLog ) RawJSON () string { return r .JSON .raw }
293+ func (r * AppDeploymentFollowResponseLog ) UnmarshalJSON (data []byte ) error {
294+ return apijson .UnmarshalRoot (data , r )
295+ }
296+
122297type AppDeploymentNewParams struct {
123298 // Relative path to the entrypoint of the application
124299 EntrypointRelPath string `json:"entrypoint_rel_path,required"`
0 commit comments