add step finish part

This commit is contained in:
Dax Raad 2025-07-10 16:21:26 -04:00
parent b00bb3c083
commit c056b0add9
4 changed files with 149 additions and 18 deletions

View file

@ -721,6 +721,11 @@ export namespace Session {
const usage = getUsage(model.info, value.usage, value.providerMetadata)
next.cost += usage.cost
next.tokens = usage.tokens
next.parts.push({
type: "step-finish",
tokens: usage.tokens,
cost: usage.cost,
})
break
case "text-start":

View file

@ -116,6 +116,25 @@ export namespace MessageV2 {
})
export type StepStartPart = z.infer<typeof StepStartPart>
export const StepFinishPart = z
.object({
type: z.literal("step-finish"),
cost: z.number(),
tokens: z.object({
input: z.number(),
output: z.number(),
reasoning: z.number(),
cache: z.object({
read: z.number(),
write: z.number(),
}),
}),
})
.openapi({
ref: "StepFinishPart",
})
export type StepFinishPart = z.infer<typeof StepFinishPart>
const Base = z.object({
id: z.string(),
sessionID: z.string(),
@ -137,9 +156,11 @@ export namespace MessageV2 {
})
export type User = z.infer<typeof User>
export const AssistantPart = z.discriminatedUnion("type", [TextPart, ToolPart, StepStartPart]).openapi({
ref: "AssistantMessagePart",
})
export const AssistantPart = z
.discriminatedUnion("type", [TextPart, ToolPart, StepStartPart, StepFinishPart])
.openapi({
ref: "AssistantMessagePart",
})
export type AssistantPart = z.infer<typeof AssistantPart>
export const Assistant = Base.extend({
@ -164,8 +185,8 @@ export namespace MessageV2 {
cwd: z.string(),
root: z.string(),
}),
cost: z.number(),
summary: z.boolean().optional(),
cost: z.number(),
tokens: z.object({
input: z.number(),
output: z.number(),

View file

@ -1,4 +1,4 @@
configured_endpoints: 22
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-37247433660e125f9a79ff173d8007f13192d28a40f4e599e002446a6ed0c128.yml
openapi_spec_hash: 8095ebe2d88259381a58e7b0c87244c4
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-eb25bb3673f94d0e98a7036e2a2b0ed7ad63d1598665f2d5e091ec0835273798.yml
openapi_spec_hash: 62f6a8a06aaa4f4ae13e85d56652724f
config_hash: 589ec6a935a43a3c49a325ece86cbda2

View file

@ -438,13 +438,17 @@ func (r AssistantMessageErrorName) IsKnown() bool {
type AssistantMessagePart struct {
Type AssistantMessagePartType `json:"type,required"`
ID string `json:"id"`
Cost float64 `json:"cost"`
// This field can have the runtime type of [ToolPartState].
State interface{} `json:"state"`
Synthetic bool `json:"synthetic"`
Text string `json:"text"`
Tool string `json:"tool"`
JSON assistantMessagePartJSON `json:"-"`
union AssistantMessagePartUnion
State interface{} `json:"state"`
Synthetic bool `json:"synthetic"`
Text string `json:"text"`
// This field can have the runtime type of
// [AssistantMessagePartStepFinishPartTokens].
Tokens interface{} `json:"tokens"`
Tool string `json:"tool"`
JSON assistantMessagePartJSON `json:"-"`
union AssistantMessagePartUnion
}
// assistantMessagePartJSON contains the JSON metadata for the struct
@ -452,9 +456,11 @@ type AssistantMessagePart struct {
type assistantMessagePartJSON struct {
Type apijson.Field
ID apijson.Field
Cost apijson.Field
State apijson.Field
Synthetic apijson.Field
Text apijson.Field
Tokens apijson.Field
Tool apijson.Field
raw string
ExtraFields map[string]apijson.Field
@ -476,12 +482,14 @@ func (r *AssistantMessagePart) UnmarshalJSON(data []byte) (err error) {
// AsUnion returns a [AssistantMessagePartUnion] interface which you can cast to
// the specific types for more type safety.
//
// Possible runtime types of the union are [TextPart], [ToolPart], [StepStartPart].
// Possible runtime types of the union are [TextPart], [ToolPart], [StepStartPart],
// [AssistantMessagePartStepFinishPart].
func (r AssistantMessagePart) AsUnion() AssistantMessagePartUnion {
return r.union
}
// Union satisfied by [TextPart], [ToolPart] or [StepStartPart].
// Union satisfied by [TextPart], [ToolPart], [StepStartPart] or
// [AssistantMessagePartStepFinishPart].
type AssistantMessagePartUnion interface {
implementsAssistantMessagePart()
}
@ -505,20 +513,117 @@ func init() {
Type: reflect.TypeOf(StepStartPart{}),
DiscriminatorValue: "step-start",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(AssistantMessagePartStepFinishPart{}),
DiscriminatorValue: "step-finish",
},
)
}
type AssistantMessagePartStepFinishPart struct {
Cost float64 `json:"cost,required"`
Tokens AssistantMessagePartStepFinishPartTokens `json:"tokens,required"`
Type AssistantMessagePartStepFinishPartType `json:"type,required"`
JSON assistantMessagePartStepFinishPartJSON `json:"-"`
}
// assistantMessagePartStepFinishPartJSON contains the JSON metadata for the struct
// [AssistantMessagePartStepFinishPart]
type assistantMessagePartStepFinishPartJSON struct {
Cost apijson.Field
Tokens apijson.Field
Type apijson.Field
raw string
ExtraFields map[string]apijson.Field
}
func (r *AssistantMessagePartStepFinishPart) UnmarshalJSON(data []byte) (err error) {
return apijson.UnmarshalRoot(data, r)
}
func (r assistantMessagePartStepFinishPartJSON) RawJSON() string {
return r.raw
}
func (r AssistantMessagePartStepFinishPart) implementsAssistantMessagePart() {}
type AssistantMessagePartStepFinishPartTokens struct {
Cache AssistantMessagePartStepFinishPartTokensCache `json:"cache,required"`
Input float64 `json:"input,required"`
Output float64 `json:"output,required"`
Reasoning float64 `json:"reasoning,required"`
JSON assistantMessagePartStepFinishPartTokensJSON `json:"-"`
}
// assistantMessagePartStepFinishPartTokensJSON contains the JSON metadata for the
// struct [AssistantMessagePartStepFinishPartTokens]
type assistantMessagePartStepFinishPartTokensJSON struct {
Cache apijson.Field
Input apijson.Field
Output apijson.Field
Reasoning apijson.Field
raw string
ExtraFields map[string]apijson.Field
}
func (r *AssistantMessagePartStepFinishPartTokens) UnmarshalJSON(data []byte) (err error) {
return apijson.UnmarshalRoot(data, r)
}
func (r assistantMessagePartStepFinishPartTokensJSON) RawJSON() string {
return r.raw
}
type AssistantMessagePartStepFinishPartTokensCache struct {
Read float64 `json:"read,required"`
Write float64 `json:"write,required"`
JSON assistantMessagePartStepFinishPartTokensCacheJSON `json:"-"`
}
// assistantMessagePartStepFinishPartTokensCacheJSON contains the JSON metadata for
// the struct [AssistantMessagePartStepFinishPartTokensCache]
type assistantMessagePartStepFinishPartTokensCacheJSON struct {
Read apijson.Field
Write apijson.Field
raw string
ExtraFields map[string]apijson.Field
}
func (r *AssistantMessagePartStepFinishPartTokensCache) UnmarshalJSON(data []byte) (err error) {
return apijson.UnmarshalRoot(data, r)
}
func (r assistantMessagePartStepFinishPartTokensCacheJSON) RawJSON() string {
return r.raw
}
type AssistantMessagePartStepFinishPartType string
const (
AssistantMessagePartStepFinishPartTypeStepFinish AssistantMessagePartStepFinishPartType = "step-finish"
)
func (r AssistantMessagePartStepFinishPartType) IsKnown() bool {
switch r {
case AssistantMessagePartStepFinishPartTypeStepFinish:
return true
}
return false
}
type AssistantMessagePartType string
const (
AssistantMessagePartTypeText AssistantMessagePartType = "text"
AssistantMessagePartTypeTool AssistantMessagePartType = "tool"
AssistantMessagePartTypeStepStart AssistantMessagePartType = "step-start"
AssistantMessagePartTypeText AssistantMessagePartType = "text"
AssistantMessagePartTypeTool AssistantMessagePartType = "tool"
AssistantMessagePartTypeStepStart AssistantMessagePartType = "step-start"
AssistantMessagePartTypeStepFinish AssistantMessagePartType = "step-finish"
)
func (r AssistantMessagePartType) IsKnown() bool {
switch r {
case AssistantMessagePartTypeText, AssistantMessagePartTypeTool, AssistantMessagePartTypeStepStart:
case AssistantMessagePartTypeText, AssistantMessagePartTypeTool, AssistantMessagePartTypeStepStart, AssistantMessagePartTypeStepFinish:
return true
}
return false