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 VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.16.0
0.17.0
70 changes: 70 additions & 0 deletions arkruntime/model/session/ark_apis_stop_reason_sync_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c) 2026 ByteDance Ltd. and/or its affiliates.
// SPDX-License-Identifier: Apache-2.0

// Synced from ark-apis by vendor-session. Tests the actual stream decoder.
package session

import (
"encoding/json"
"reflect"
"testing"
)

func TestArkAPISStreamStopReasonEventIDs(t *testing.T) {
for _, kind := range []string{"session.status_idle", "session.thread_status_idle"} {
for _, ids := range [][]string{{"sevt-a", "sevt-b"}, {"sevt-b"}, {}} {
payload := map[string]interface{}{
"type": kind, "id": "sevt-idle",
"stop_reason": map[string]interface{}{"type": "requires_action", "event_ids": ids},
}
if kind == "session.thread_status_idle" {
payload["session_thread_id"] = "sthr-1"
payload["agent_name"] = "agent"
}
raw, err := json.Marshal(payload)
if err != nil {
t.Fatal(err)
}
event := decodeSessionEvent(raw)
var reason *ManagedAgentsStopReason
switch event := event.(type) {
case *ManagedAgentsSessionStatusIdleEvent:
reason = event.StopReason
case *ManagedAgentsSessionThreadStatusIdleEvent:
reason = event.StopReason
default:
t.Fatalf("unexpected event %T", event)
}
if reason == nil || reason.Type != "requires_action" || reason.EventIDs == nil || !reflect.DeepEqual(*reason.EventIDs, ids) {
t.Fatalf("lost pending event IDs: %#v", reason)
}
encoded, err := json.Marshal(event)
if err != nil {
t.Fatal(err)
}
var before, after interface{}
if err := json.Unmarshal(raw, &before); err != nil {
t.Fatal(err)
}
if err := json.Unmarshal(encoded, &after); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(before, after) {
t.Fatalf("wire shape changed: %s -> %s", raw, encoded)
}
}
}
}

func TestArkAPISLegacyStopReason(t *testing.T) {
for _, kind := range []string{"end_turn", "retries_exhausted", "future_reason"} {
reason := ManagedAgentsStopReason{Type: kind}
encoded, err := json.Marshal(reason)
if err != nil {
t.Fatal(err)
}
if string(encoded) != `{"type":"`+kind+`"}` {
t.Fatalf("legacy stop reason changed: %s", encoded)
}
}
}
2 changes: 2 additions & 0 deletions arkruntime/model/session/session_stream_shim.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ func (e sessionEventBase) GetProcessedAt() string { return e.ProcessedAt }
// Common values: "end_turn", "retries_exhausted", "user_interrupt".
type ManagedAgentsStopReason struct {
Type string `json:"type"`
// Pending input event IDs when Type is requires_action.
EventIDs *[]string `json:"event_ids,omitempty"`
}

// ManagedAgentsRetryStatus optionally accompanies a session error to
Expand Down
Loading