mirror of
https://github.com/sst/opencode.git
synced 2025-08-04 21:38:01 +00:00
chore: rework openapi spec and use stainless sdk
This commit is contained in:
parent
226a4a7f36
commit
79bbf90b72
28 changed files with 658 additions and 6634 deletions
|
@ -9,13 +9,13 @@ import (
|
|||
"github.com/charmbracelet/bubbles/v2/viewport"
|
||||
tea "github.com/charmbracelet/bubbletea/v2"
|
||||
"github.com/charmbracelet/lipgloss/v2"
|
||||
"github.com/sst/opencode-sdk-go"
|
||||
"github.com/sst/opencode/internal/app"
|
||||
"github.com/sst/opencode/internal/components/commands"
|
||||
"github.com/sst/opencode/internal/components/dialog"
|
||||
"github.com/sst/opencode/internal/layout"
|
||||
"github.com/sst/opencode/internal/styles"
|
||||
"github.com/sst/opencode/internal/theme"
|
||||
"github.com/sst/opencode/pkg/client"
|
||||
)
|
||||
|
||||
type MessagesComponent interface {
|
||||
|
@ -83,7 +83,7 @@ func (m *messagesComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
if m.tail {
|
||||
m.viewport.GotoBottom()
|
||||
}
|
||||
case client.EventSessionUpdated, client.EventMessageUpdated:
|
||||
case opencode.EventListResponseEventSessionUpdated, opencode.EventListResponseEventMessageUpdated:
|
||||
m.renderView()
|
||||
if m.tail {
|
||||
m.viewport.GotoBottom()
|
||||
|
@ -130,90 +130,97 @@ func (m *messagesComponent) renderView() {
|
|||
lastToolIndex := 0
|
||||
lastToolIndices := []int{}
|
||||
for i, p := range message.Parts {
|
||||
part, _ := p.ValueByDiscriminator()
|
||||
switch part.(type) {
|
||||
case client.MessagePartText:
|
||||
switch p.Type {
|
||||
case opencode.MessagePartTypeText:
|
||||
lastToolIndices = append(lastToolIndices, lastToolIndex)
|
||||
case client.MessagePartToolInvocation:
|
||||
case opencode.MessagePartTypeToolInvocation:
|
||||
lastToolIndex = i
|
||||
}
|
||||
}
|
||||
|
||||
author := ""
|
||||
switch message.Role {
|
||||
case client.User:
|
||||
case opencode.MessageRoleUser:
|
||||
author = m.app.Info.User
|
||||
case client.Assistant:
|
||||
case opencode.MessageRoleAssistant:
|
||||
author = message.Metadata.Assistant.ModelID
|
||||
}
|
||||
|
||||
for i, p := range message.Parts {
|
||||
part, err := p.ValueByDiscriminator()
|
||||
if err != nil {
|
||||
continue //TODO: handle error?
|
||||
}
|
||||
|
||||
switch part.(type) {
|
||||
switch part := p.AsUnion().(type) {
|
||||
// case client.MessagePartStepStart:
|
||||
// messages = append(messages, "")
|
||||
case client.MessagePartText:
|
||||
text := part.(client.MessagePartText)
|
||||
key := m.cache.GenerateKey(message.Id, text.Text, layout.Current.Viewport.Width)
|
||||
case opencode.TextPart:
|
||||
key := m.cache.GenerateKey(message.ID, p.Text, layout.Current.Viewport.Width)
|
||||
content, cached = m.cache.Get(key)
|
||||
if !cached {
|
||||
content = renderText(message, text.Text, author)
|
||||
content = renderText(message, p.Text, author)
|
||||
m.cache.Set(key, content)
|
||||
}
|
||||
if previousBlockType != none {
|
||||
blocks = append(blocks, "")
|
||||
}
|
||||
blocks = append(blocks, content)
|
||||
if message.Role == client.User {
|
||||
if message.Role == opencode.MessageRoleUser {
|
||||
previousBlockType = userTextBlock
|
||||
} else if message.Role == client.Assistant {
|
||||
} else if message.Role == opencode.MessageRoleAssistant {
|
||||
previousBlockType = assistantTextBlock
|
||||
}
|
||||
case client.MessagePartToolInvocation:
|
||||
case opencode.ToolInvocationPart:
|
||||
isLastToolInvocation := slices.Contains(lastToolIndices, i)
|
||||
toolInvocationPart := part.(client.MessagePartToolInvocation)
|
||||
toolCall, _ := toolInvocationPart.ToolInvocation.AsMessageToolInvocationToolCall()
|
||||
metadata := client.MessageMetadata_Tool_AdditionalProperties{}
|
||||
if _, ok := message.Metadata.Tool[toolCall.ToolCallId]; ok {
|
||||
metadata = message.Metadata.Tool[toolCall.ToolCallId]
|
||||
}
|
||||
var result *string
|
||||
resultPart, resultError := toolInvocationPart.ToolInvocation.AsMessageToolInvocationToolResult()
|
||||
if resultError == nil {
|
||||
result = &resultPart.Result
|
||||
metadata := opencode.MessageMetadataTool{}
|
||||
|
||||
toolCallID := part.ToolInvocation.ToolCallID
|
||||
// var toolCallID string
|
||||
// var result *string
|
||||
// switch toolCall := part.ToolInvocation.AsUnion().(type) {
|
||||
// case opencode.ToolCall:
|
||||
// toolCallID = toolCall.ToolCallID
|
||||
// case opencode.ToolPartialCall:
|
||||
// toolCallID = toolCall.ToolCallID
|
||||
// case opencode.ToolResult:
|
||||
// toolCallID = toolCall.ToolCallID
|
||||
// result = &toolCall.Result
|
||||
// }
|
||||
|
||||
if _, ok := message.Metadata.Tool[toolCallID]; ok {
|
||||
metadata = message.Metadata.Tool[toolCallID]
|
||||
}
|
||||
|
||||
if toolCall.State == "result" {
|
||||
key := m.cache.GenerateKey(message.Id,
|
||||
toolCall.ToolCallId,
|
||||
var result *string
|
||||
if part.ToolInvocation.Result != "" {
|
||||
result = &part.ToolInvocation.Result
|
||||
}
|
||||
|
||||
if part.ToolInvocation.State == "result" {
|
||||
key := m.cache.GenerateKey(message.ID,
|
||||
part.ToolInvocation.ToolCallID,
|
||||
m.showToolDetails,
|
||||
layout.Current.Viewport.Width,
|
||||
)
|
||||
content, cached = m.cache.Get(key)
|
||||
if !cached {
|
||||
content = renderToolInvocation(
|
||||
toolCall,
|
||||
part,
|
||||
result,
|
||||
metadata,
|
||||
m.showToolDetails,
|
||||
isLastToolInvocation,
|
||||
false,
|
||||
message.Metadata,
|
||||
)
|
||||
m.cache.Set(key, content)
|
||||
}
|
||||
} else {
|
||||
// if the tool call isn't finished, don't cache
|
||||
content = renderToolInvocation(
|
||||
toolCall,
|
||||
part,
|
||||
result,
|
||||
metadata,
|
||||
m.showToolDetails,
|
||||
isLastToolInvocation,
|
||||
false,
|
||||
message.Metadata,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -226,16 +233,17 @@ func (m *messagesComponent) renderView() {
|
|||
}
|
||||
|
||||
error := ""
|
||||
if message.Metadata.Error != nil {
|
||||
errorValue, _ := message.Metadata.Error.ValueByDiscriminator()
|
||||
switch errorValue.(type) {
|
||||
case client.UnknownError:
|
||||
clientError := errorValue.(client.UnknownError)
|
||||
error = clientError.Data.Message
|
||||
error = renderContentBlock(error, WithBorderColor(t.Error()), WithFullWidth(), WithMarginTop(1), WithMarginBottom(1))
|
||||
blocks = append(blocks, error)
|
||||
previousBlockType = errorBlock
|
||||
}
|
||||
switch err := message.Metadata.Error.AsUnion().(type) {
|
||||
case nil:
|
||||
default:
|
||||
clientError := err.(opencode.UnknownError)
|
||||
error = clientError.Data.Message
|
||||
}
|
||||
|
||||
if error != "" {
|
||||
error = renderContentBlock(error, WithBorderColor(t.Error()), WithFullWidth(), WithMarginTop(1), WithMarginBottom(1))
|
||||
blocks = append(blocks, error)
|
||||
previousBlockType = errorBlock
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,7 +262,7 @@ func (m *messagesComponent) renderView() {
|
|||
}
|
||||
|
||||
func (m *messagesComponent) header() string {
|
||||
if m.app.Session.Id == "" {
|
||||
if m.app.Session.ID == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
|
@ -264,8 +272,8 @@ func (m *messagesComponent) header() string {
|
|||
muted := styles.NewStyle().Foreground(t.TextMuted()).Background(t.Background()).Render
|
||||
headerLines := []string{}
|
||||
headerLines = append(headerLines, toMarkdown("# "+m.app.Session.Title, width-6, t.Background()))
|
||||
if m.app.Session.Share != nil && m.app.Session.Share.Url != "" {
|
||||
headerLines = append(headerLines, muted(m.app.Session.Share.Url))
|
||||
if m.app.Session.Share.URL != "" {
|
||||
headerLines = append(headerLines, muted(m.app.Session.Share.URL))
|
||||
} else {
|
||||
headerLines = append(headerLines, base("/share")+muted(" to create a shareable link"))
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue