feat: thinking blocks rendered in tui and share page

This commit is contained in:
adamdotdevin
2025-08-10 19:24:16 -05:00
parent 20e818ad05
commit b8d2aebf09
17 changed files with 324 additions and 55 deletions

View File

@@ -1,4 +1,4 @@
configured_endpoints: 34
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-da1c340135c3dd6b1edb4e00e7039d2ac54d59271683a8b6ed528e51137ce41a.yml
openapi_spec_hash: 0cdd9b6273d72f5a6f484a2999ff0632
config_hash: 7581d5948150d4ef7dd7b13d0845dbeb
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-b86cf7bb8df4f60ebe8b8f51e281c8076cfdccc8554178c1b78beca4b025f0ff.yml
openapi_spec_hash: 47633b7481d91708643ea7b43fffffe6
config_hash: bd7f6435ed0c0005f373b5526c07a055

View File

@@ -92,6 +92,7 @@ Response Types:
- <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#FileSource">FileSource</a>
- <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#Message">Message</a>
- <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#Part">Part</a>
- <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#ReasoningPart">ReasoningPart</a>
- <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#Session">Session</a>
- <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SnapshotPart">SnapshotPart</a>
- <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#StepFinishPart">StepFinishPart</a>

View File

@@ -74,9 +74,10 @@ type Config struct {
// Control sharing behavior:'manual' allows manual sharing via commands, 'auto'
// enables automatic sharing, 'disabled' disables all sharing
Share ConfigShare `json:"share"`
// Small model to use for tasks like title generation in the
// format of provider/model
// Small model to use for tasks like title generation in the format of
// provider/model
SmallModel string `json:"small_model"`
Snapshot bool `json:"snapshot"`
// Theme name to use for the interface
Theme string `json:"theme"`
// Custom username to display in conversations instead of system username
@@ -105,6 +106,7 @@ type configJSON struct {
Provider apijson.Field
Share apijson.Field
SmallModel apijson.Field
Snapshot apijson.Field
Theme apijson.Field
Username apijson.Field
raw string
@@ -780,9 +782,10 @@ func (r ConfigModePlanMode) IsKnown() bool {
}
type ConfigPermission struct {
Bash ConfigPermissionBashUnion `json:"bash"`
Edit ConfigPermissionEdit `json:"edit"`
JSON configPermissionJSON `json:"-"`
Bash ConfigPermissionBashUnion `json:"bash"`
Edit ConfigPermissionEdit `json:"edit"`
Webfetch ConfigPermissionWebfetch `json:"webfetch"`
JSON configPermissionJSON `json:"-"`
}
// configPermissionJSON contains the JSON metadata for the struct
@@ -790,6 +793,7 @@ type ConfigPermission struct {
type configPermissionJSON struct {
Bash apijson.Field
Edit apijson.Field
Webfetch apijson.Field
raw string
ExtraFields map[string]apijson.Field
}
@@ -876,6 +880,22 @@ func (r ConfigPermissionEdit) IsKnown() bool {
return false
}
type ConfigPermissionWebfetch string
const (
ConfigPermissionWebfetchAsk ConfigPermissionWebfetch = "ask"
ConfigPermissionWebfetchAllow ConfigPermissionWebfetch = "allow"
ConfigPermissionWebfetchDeny ConfigPermissionWebfetch = "deny"
)
func (r ConfigPermissionWebfetch) IsKnown() bool {
switch r {
case ConfigPermissionWebfetchAsk, ConfigPermissionWebfetchAllow, ConfigPermissionWebfetchDeny:
return true
}
return false
}
type ConfigProvider struct {
Models map[string]ConfigProviderModel `json:"models,required"`
ID string `json:"id"`

View File

@@ -21,7 +21,7 @@ echo "==> Starting mock server with URL ${URL}"
# Run prism mock on the given spec
if [ "$1" == "--daemon" ]; then
npm exec --package=@stainless-api/prism-cli@5.8.5 -- prism mock "$URL" &> .prism.log &
npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log &
# Wait for server to come online
echo -n "Waiting for server"
@@ -37,5 +37,5 @@ if [ "$1" == "--daemon" ]; then
echo
else
npm exec --package=@stainless-api/prism-cli@5.8.5 -- prism mock "$URL"
npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL"
fi

View File

@@ -43,7 +43,7 @@ elif ! prism_is_running ; then
echo -e "To run the server, pass in the path or url of your OpenAPI"
echo -e "spec to the prism command:"
echo
echo -e " \$ ${YELLOW}npm exec --package=@stoplight/prism-cli@~5.3.2 -- prism mock path/to/your.openapi.yml${NC}"
echo -e " \$ ${YELLOW}npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock path/to/your.openapi.yml${NC}"
echo
exit 1

View File

@@ -962,18 +962,20 @@ type Part struct {
Cost float64 `json:"cost"`
Filename string `json:"filename"`
// This field can have the runtime type of [[]string].
Files interface{} `json:"files"`
Hash string `json:"hash"`
Mime string `json:"mime"`
Name string `json:"name"`
Snapshot string `json:"snapshot"`
Files interface{} `json:"files"`
Hash string `json:"hash"`
Mime string `json:"mime"`
Name string `json:"name"`
// This field can have the runtime type of [map[string]interface{}].
ProviderMetadata interface{} `json:"providerMetadata"`
Snapshot string `json:"snapshot"`
// This field can have the runtime type of [FilePartSource], [AgentPartSource].
Source interface{} `json:"source"`
// This field can have the runtime type of [ToolPartState].
State interface{} `json:"state"`
Synthetic bool `json:"synthetic"`
Text string `json:"text"`
// This field can have the runtime type of [TextPartTime].
// This field can have the runtime type of [TextPartTime], [ReasoningPartTime].
Time interface{} `json:"time"`
// This field can have the runtime type of [StepFinishPartTokens].
Tokens interface{} `json:"tokens"`
@@ -985,28 +987,29 @@ type Part struct {
// partJSON contains the JSON metadata for the struct [Part]
type partJSON struct {
ID apijson.Field
MessageID apijson.Field
SessionID apijson.Field
Type apijson.Field
CallID apijson.Field
Cost apijson.Field
Filename apijson.Field
Files apijson.Field
Hash apijson.Field
Mime apijson.Field
Name apijson.Field
Snapshot apijson.Field
Source apijson.Field
State apijson.Field
Synthetic apijson.Field
Text apijson.Field
Time apijson.Field
Tokens apijson.Field
Tool apijson.Field
URL apijson.Field
raw string
ExtraFields map[string]apijson.Field
ID apijson.Field
MessageID apijson.Field
SessionID apijson.Field
Type apijson.Field
CallID apijson.Field
Cost apijson.Field
Filename apijson.Field
Files apijson.Field
Hash apijson.Field
Mime apijson.Field
Name apijson.Field
ProviderMetadata apijson.Field
Snapshot apijson.Field
Source apijson.Field
State apijson.Field
Synthetic apijson.Field
Text apijson.Field
Time apijson.Field
Tokens apijson.Field
Tool apijson.Field
URL apijson.Field
raw string
ExtraFields map[string]apijson.Field
}
func (r partJSON) RawJSON() string {
@@ -1025,14 +1028,16 @@ func (r *Part) UnmarshalJSON(data []byte) (err error) {
// AsUnion returns a [PartUnion] interface which you can cast to the specific types
// for more type safety.
//
// Possible runtime types of the union are [TextPart], [FilePart], [ToolPart],
// [StepStartPart], [StepFinishPart], [SnapshotPart], [PartPatchPart], [AgentPart].
// Possible runtime types of the union are [TextPart], [ReasoningPart], [FilePart],
// [ToolPart], [StepStartPart], [StepFinishPart], [SnapshotPart], [PartPatchPart],
// [AgentPart].
func (r Part) AsUnion() PartUnion {
return r.union
}
// Union satisfied by [TextPart], [FilePart], [ToolPart], [StepStartPart],
// [StepFinishPart], [SnapshotPart], [PartPatchPart] or [AgentPart].
// Union satisfied by [TextPart], [ReasoningPart], [FilePart], [ToolPart],
// [StepStartPart], [StepFinishPart], [SnapshotPart], [PartPatchPart] or
// [AgentPart].
type PartUnion interface {
implementsPart()
}
@@ -1046,6 +1051,11 @@ func init() {
Type: reflect.TypeOf(TextPart{}),
DiscriminatorValue: "text",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(ReasoningPart{}),
DiscriminatorValue: "reasoning",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(FilePart{}),
@@ -1134,6 +1144,7 @@ type PartType string
const (
PartTypeText PartType = "text"
PartTypeReasoning PartType = "reasoning"
PartTypeFile PartType = "file"
PartTypeTool PartType = "tool"
PartTypeStepStart PartType = "step-start"
@@ -1145,12 +1156,83 @@ const (
func (r PartType) IsKnown() bool {
switch r {
case PartTypeText, PartTypeFile, PartTypeTool, PartTypeStepStart, PartTypeStepFinish, PartTypeSnapshot, PartTypePatch, PartTypeAgent:
case PartTypeText, PartTypeReasoning, PartTypeFile, PartTypeTool, PartTypeStepStart, PartTypeStepFinish, PartTypeSnapshot, PartTypePatch, PartTypeAgent:
return true
}
return false
}
type ReasoningPart struct {
ID string `json:"id,required"`
MessageID string `json:"messageID,required"`
SessionID string `json:"sessionID,required"`
Text string `json:"text,required"`
Type ReasoningPartType `json:"type,required"`
ProviderMetadata map[string]interface{} `json:"providerMetadata"`
Time ReasoningPartTime `json:"time"`
JSON reasoningPartJSON `json:"-"`
}
// reasoningPartJSON contains the JSON metadata for the struct [ReasoningPart]
type reasoningPartJSON struct {
ID apijson.Field
MessageID apijson.Field
SessionID apijson.Field
Text apijson.Field
Type apijson.Field
ProviderMetadata apijson.Field
Time apijson.Field
raw string
ExtraFields map[string]apijson.Field
}
func (r *ReasoningPart) UnmarshalJSON(data []byte) (err error) {
return apijson.UnmarshalRoot(data, r)
}
func (r reasoningPartJSON) RawJSON() string {
return r.raw
}
func (r ReasoningPart) implementsPart() {}
type ReasoningPartType string
const (
ReasoningPartTypeReasoning ReasoningPartType = "reasoning"
)
func (r ReasoningPartType) IsKnown() bool {
switch r {
case ReasoningPartTypeReasoning:
return true
}
return false
}
type ReasoningPartTime struct {
Start float64 `json:"start,required"`
End float64 `json:"end"`
JSON reasoningPartTimeJSON `json:"-"`
}
// reasoningPartTimeJSON contains the JSON metadata for the struct
// [ReasoningPartTime]
type reasoningPartTimeJSON struct {
Start apijson.Field
End apijson.Field
raw string
ExtraFields map[string]apijson.Field
}
func (r *ReasoningPartTime) UnmarshalJSON(data []byte) (err error) {
return apijson.UnmarshalRoot(data, r)
}
func (r reasoningPartTimeJSON) RawJSON() string {
return r.raw
}
type Session struct {
ID string `json:"id,required"`
Time SessionTime `json:"time,required"`