summaryrefslogtreecommitdiffhomepage
path: root/packages/tui/internal/components
diff options
context:
space:
mode:
authoradamdottv <[email protected]>2025-06-27 07:46:42 -0500
committerJay V <[email protected]>2025-06-27 19:10:42 -0400
commitbe0811ecc30bb8a4fef14111437aacf6fa51fe27 (patch)
tree737ca49413e16756e2c2d779f9e3961fae4e7d13 /packages/tui/internal/components
parent0676bcd4fd33b6acb37e248be53b9e6a0352be6b (diff)
downloadopencode-be0811ecc30bb8a4fef14111437aacf6fa51fe27.tar.gz
opencode-be0811ecc30bb8a4fef14111437aacf6fa51fe27.zip
chore: rework openapi spec and use stainless sdk
Diffstat (limited to 'packages/tui/internal/components')
-rw-r--r--packages/tui/internal/components/chat/message.go129
-rw-r--r--packages/tui/internal/components/chat/messages.go102
-rw-r--r--packages/tui/internal/components/commands/commands.go2
-rw-r--r--packages/tui/internal/components/dialog/models.go24
-rw-r--r--packages/tui/internal/components/dialog/session.go10
-rw-r--r--packages/tui/internal/components/status/status.go12
6 files changed, 149 insertions, 130 deletions
diff --git a/packages/tui/internal/components/chat/message.go b/packages/tui/internal/components/chat/message.go
index 6fa52c1f4..cf4662d53 100644
--- a/packages/tui/internal/components/chat/message.go
+++ b/packages/tui/internal/components/chat/message.go
@@ -12,12 +12,13 @@ import (
"github.com/charmbracelet/lipgloss/v2"
"github.com/charmbracelet/lipgloss/v2/compat"
"github.com/charmbracelet/x/ansi"
+ "github.com/sst/opencode-sdk-go"
"github.com/sst/opencode/internal/app"
"github.com/sst/opencode/internal/components/diff"
"github.com/sst/opencode/internal/layout"
"github.com/sst/opencode/internal/styles"
"github.com/sst/opencode/internal/theme"
- "github.com/sst/opencode/pkg/client"
+ "github.com/tidwall/gjson"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
@@ -209,7 +210,7 @@ func calculatePadding() int {
}
}
-func renderText(message client.MessageInfo, text string, author string) string {
+func renderText(message opencode.Message, text string, author string) string {
t := theme.CurrentTheme()
width := layout.Current.Container.Width
padding := calculatePadding()
@@ -223,7 +224,7 @@ func renderText(message client.MessageInfo, text string, author string) string {
textWidth := max(lipgloss.Width(text), lipgloss.Width(info))
markdownWidth := min(textWidth, width-padding-4) // -4 for the border and padding
- if message.Role == client.Assistant {
+ if message.Role == opencode.MessageRoleAssistant {
markdownWidth = width - padding - 4 - 3
}
minWidth := max(markdownWidth, (width-4)/2)
@@ -235,18 +236,18 @@ func renderText(message client.MessageInfo, text string, author string) string {
messageStyle = messageStyle.AlignHorizontal(lipgloss.Right)
}
content := messageStyle.Render(text)
- if message.Role == client.Assistant {
+ if message.Role == opencode.MessageRoleAssistant {
content = toMarkdown(text, markdownWidth, t.BackgroundPanel())
}
content = strings.Join([]string{content, info}, "\n")
switch message.Role {
- case client.User:
+ case opencode.MessageRoleUser:
return renderContentBlock(content,
WithAlign(lipgloss.Right),
WithBorderColor(t.Secondary()),
)
- case client.Assistant:
+ case opencode.MessageRoleAssistant:
return renderContentBlock(content,
WithAlign(lipgloss.Left),
WithBorderColor(t.Accent()),
@@ -256,15 +257,16 @@ func renderText(message client.MessageInfo, text string, author string) string {
}
func renderToolInvocation(
- toolCall client.MessageToolInvocationToolCall,
+ toolCall opencode.ToolInvocationPart,
result *string,
- metadata client.MessageMetadata_Tool_AdditionalProperties,
+ metadata opencode.MessageMetadataTool,
showDetails bool,
isLast bool,
contentOnly bool,
+ messageMetadata opencode.MessageMetadata,
) string {
ignoredTools := []string{"todoread"}
- if slices.Contains(ignoredTools, toolCall.ToolName) {
+ if slices.Contains(ignoredTools, toolCall.ToolInvocation.ToolName) {
return ""
}
@@ -294,8 +296,8 @@ func renderToolInvocation(
BorderForeground(t.BackgroundPanel()).
BorderStyle(lipgloss.ThickBorder())
- if toolCall.State == "partial-call" {
- title := renderToolAction(toolCall.ToolName)
+ if toolCall.ToolInvocation.State == "partial-call" {
+ title := renderToolAction(toolCall.ToolInvocation.ToolName)
if !showDetails {
title = "∟ " + title
padding := calculatePadding()
@@ -316,8 +318,8 @@ func renderToolInvocation(
toolArgs := ""
toolArgsMap := make(map[string]any)
- if toolCall.Args != nil {
- value := *toolCall.Args
+ if toolCall.ToolInvocation.Args != nil {
+ value := toolCall.ToolInvocation.Args
if m, ok := value.(map[string]any); ok {
toolArgsMap = m
@@ -339,28 +341,35 @@ func renderToolInvocation(
error := ""
finished := result != nil && *result != ""
- if e, ok := metadata.Get("error"); ok && e.(bool) == true {
- if m, ok := metadata.Get("message"); ok {
- style = style.BorderLeftForeground(t.Error())
- error = styles.NewStyle().
- Foreground(t.Error()).
- Background(t.BackgroundPanel()).
- Render(m.(string))
- error = renderContentBlock(
- error,
- WithFullWidth(),
- WithBorderColor(t.Error()),
- WithMarginBottom(1),
- )
- }
+ er := messageMetadata.Error.AsUnion()
+ switch er.(type) {
+ case nil:
+ default:
+ clientError := er.(opencode.UnknownError)
+ error = clientError.Data.Message
+ }
+
+ if error != "" {
+ style = style.BorderLeftForeground(t.Error())
+ error = styles.NewStyle().
+ Foreground(t.Error()).
+ Background(t.BackgroundPanel()).
+ Render(error)
+ error = renderContentBlock(
+ error,
+ WithFullWidth(),
+ WithBorderColor(t.Error()),
+ WithMarginBottom(1),
+ )
}
title := ""
- switch toolCall.ToolName {
+ switch toolCall.ToolInvocation.ToolName {
case "read":
toolArgs = renderArgs(&toolArgsMap, "filePath")
title = fmt.Sprintf("READ %s", toolArgs)
- if preview, ok := metadata.Get("preview"); ok && toolArgsMap["filePath"] != nil {
+ preview := metadata.ExtraFields["preview"]
+ if preview != nil && toolArgsMap["filePath"] != nil {
filename := toolArgsMap["filePath"].(string)
body = preview.(string)
body = renderFile(filename, body, WithTruncate(6))
@@ -368,8 +377,9 @@ func renderToolInvocation(
case "edit":
if filename, ok := toolArgsMap["filePath"].(string); ok {
title = fmt.Sprintf("EDIT %s", relative(filename))
- if d, ok := metadata.Get("diff"); ok {
- patch := d.(string)
+ diffField := metadata.ExtraFields["diff"]
+ if diffField != nil {
+ patch := diffField.(string)
var formattedDiff string
if layout.Current.Viewport.Width < 80 {
formattedDiff, _ = diff.FormatUnifiedDiff(
@@ -406,7 +416,7 @@ func renderToolInvocation(
)
// Add diagnostics at the bottom if they exist
- if diagnostics := renderDiagnostics(metadata, filename); diagnostics != "" {
+ if diagnostics := renderDiagnostics(messageMetadata, filename); diagnostics != "" {
body += "\n" + renderContentBlock(diagnostics, WithFullWidth(), WithBorderColor(t.Error()))
}
}
@@ -418,7 +428,7 @@ func renderToolInvocation(
body = renderFile(filename, content)
// Add diagnostics at the bottom if they exist
- if diagnostics := renderDiagnostics(metadata, filename); diagnostics != "" {
+ if diagnostics := renderDiagnostics(messageMetadata, filename); diagnostics != "" {
body += "\n" + renderContentBlock(diagnostics, WithFullWidth(), WithBorderColor(t.Error()))
}
}
@@ -427,9 +437,10 @@ func renderToolInvocation(
if description, ok := toolArgsMap["description"].(string); ok {
title = fmt.Sprintf("SHELL %s", description)
}
- if stdout, ok := metadata.Get("stdout"); ok {
+ stdout := metadata.JSON.ExtraFields["stdout"]
+ if !stdout.IsNull() {
command := toolArgsMap["command"].(string)
- stdout := stdout.(string)
+ stdout := stdout.Raw()
body = fmt.Sprintf("```console\n> %s\n%s```", command, stdout)
body = toMarkdown(body, innerWidth, t.BackgroundPanel())
body = renderContentBlock(body, WithFullWidth(), WithMarginBottom(1))
@@ -450,12 +461,13 @@ func renderToolInvocation(
case "todowrite":
title = fmt.Sprintf("PLAN")
- if to, ok := metadata.Get("todos"); ok && finished {
- todos := to.([]any)
- for _, todo := range todos {
- t := todo.(map[string]any)
- content := t["content"].(string)
- switch t["status"].(string) {
+ todos := metadata.JSON.ExtraFields["todos"]
+ if !todos.IsNull() && finished {
+ strTodos := todos.Raw()
+ todos := gjson.Parse(strTodos)
+ for _, todo := range todos.Array() {
+ content := todo.Get("content").String()
+ switch todo.Get("status").String() {
case "completed":
body += fmt.Sprintf("- [x] %s\n", content)
// case "in-progress":
@@ -470,21 +482,22 @@ func renderToolInvocation(
case "task":
if description, ok := toolArgsMap["description"].(string); ok {
title = fmt.Sprintf("TASK %s", description)
- if summary, ok := metadata.Get("summary"); ok {
- toolcalls := summary.([]any)
- // toolcalls :=
+ summary := metadata.JSON.ExtraFields["summary"]
+ if !summary.IsNull() {
+ strValue := summary.Raw()
+ toolcalls := gjson.Parse(strValue).Array()
steps := []string{}
for _, toolcall := range toolcalls {
- call := toolcall.(map[string]any)
+ call := toolcall.Value().(map[string]any)
if toolInvocation, ok := call["toolInvocation"].(map[string]any); ok {
data, _ := json.Marshal(toolInvocation)
- var toolCall client.MessageToolInvocationToolCall
+ var toolCall opencode.ToolInvocationPart
_ = json.Unmarshal(data, &toolCall)
if metadata, ok := call["metadata"].(map[string]any); ok {
data, _ = json.Marshal(metadata)
- var toolMetadata client.MessageMetadata_Tool_AdditionalProperties
+ var toolMetadata opencode.MessageMetadataTool
_ = json.Unmarshal(data, &toolMetadata)
step := renderToolInvocation(
@@ -494,6 +507,7 @@ func renderToolInvocation(
false,
false,
true,
+ messageMetadata,
)
steps = append(steps, step)
}
@@ -505,7 +519,7 @@ func renderToolInvocation(
}
default:
- toolName := renderToolName(toolCall.ToolName)
+ toolName := renderToolName(toolCall.ToolInvocation.ToolName)
title = fmt.Sprintf("%s %s", toolName, toolArgs)
if result == nil {
empty := ""
@@ -537,7 +551,7 @@ func renderToolInvocation(
)
}
- if body == "" && error == "" {
+ if body == "" && error == "" && result != nil {
body = *result
body = truncateHeight(body, 10)
body = renderContentBlock(body, WithFullWidth(), WithMarginBottom(1))
@@ -716,31 +730,28 @@ type Diagnostic struct {
}
// renderDiagnostics formats LSP diagnostics for display in the TUI
-func renderDiagnostics(metadata client.MessageMetadata_Tool_AdditionalProperties, filePath string) string {
- diagnosticsData, ok := metadata.Get("diagnostics")
- if !ok {
+func renderDiagnostics(metadata opencode.MessageMetadata, filePath string) string {
+ diagnosticsData := metadata.JSON.ExtraFields["diagnostics"]
+ if diagnosticsData.IsNull() {
return ""
}
// diagnosticsData should be a map[string][]Diagnostic
- diagnosticsMap, ok := diagnosticsData.(map[string]interface{})
- if !ok {
- return ""
- }
-
+ strDiagnosticsData := diagnosticsData.Raw()
+ diagnosticsMap := gjson.Parse(strDiagnosticsData).Value().(map[string]any)
fileDiagnostics, ok := diagnosticsMap[filePath]
if !ok {
return ""
}
- diagnosticsList, ok := fileDiagnostics.([]interface{})
+ diagnosticsList, ok := fileDiagnostics.([]any)
if !ok {
return ""
}
var errorDiagnostics []string
for _, diagInterface := range diagnosticsList {
- diagMap, ok := diagInterface.(map[string]interface{})
+ diagMap, ok := diagInterface.(map[string]any)
if !ok {
continue
}
diff --git a/packages/tui/internal/components/chat/messages.go b/packages/tui/internal/components/chat/messages.go
index da45545c9..e1c7a9d14 100644
--- a/packages/tui/internal/components/chat/messages.go
+++ b/packages/tui/internal/components/chat/messages.go
@@ -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]
+ 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]
}
+
var result *string
- resultPart, resultError := toolInvocationPart.ToolInvocation.AsMessageToolInvocationToolResult()
- if resultError == nil {
- result = &resultPart.Result
+ if part.ToolInvocation.Result != "" {
+ result = &part.ToolInvocation.Result
}
- if toolCall.State == "result" {
- key := m.cache.GenerateKey(message.Id,
- toolCall.ToolCallId,
+ 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"))
}
diff --git a/packages/tui/internal/components/commands/commands.go b/packages/tui/internal/components/commands/commands.go
index d7f334c35..e20755575 100644
--- a/packages/tui/internal/components/commands/commands.go
+++ b/packages/tui/internal/components/commands/commands.go
@@ -128,7 +128,7 @@ func (c *commandsComponent) View() string {
if c.showKeybinds {
for _, kb := range cmd.Keybindings {
if kb.RequiresLeader {
- keybindStrs = append(keybindStrs, *c.app.Config.Keybinds.Leader+" "+kb.Key)
+ keybindStrs = append(keybindStrs, c.app.Config.Keybinds.Leader+" "+kb.Key)
} else {
keybindStrs = append(keybindStrs, kb.Key)
}
diff --git a/packages/tui/internal/components/dialog/models.go b/packages/tui/internal/components/dialog/models.go
index 52ece493f..b43d48156 100644
--- a/packages/tui/internal/components/dialog/models.go
+++ b/packages/tui/internal/components/dialog/models.go
@@ -10,6 +10,7 @@ import (
"github.com/charmbracelet/bubbles/v2/key"
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/list"
"github.com/sst/opencode/internal/components/modal"
@@ -17,7 +18,6 @@ import (
"github.com/sst/opencode/internal/styles"
"github.com/sst/opencode/internal/theme"
"github.com/sst/opencode/internal/util"
- "github.com/sst/opencode/pkg/client"
)
const (
@@ -32,8 +32,8 @@ type ModelDialog interface {
type modelDialog struct {
app *app.App
- availableProviders []client.ProviderInfo
- provider client.ProviderInfo
+ availableProviders []opencode.Provider
+ provider opencode.Provider
width int
height int
hScrollOffset int
@@ -69,7 +69,7 @@ var modelKeys = modelKeyMap{
}
func (m *modelDialog) Init() tea.Cmd {
- m.setupModelsForProvider(m.provider.Id)
+ m.setupModelsForProvider(m.provider.ID)
return nil
}
@@ -90,7 +90,7 @@ func (m *modelDialog) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case key.Matches(msg, modelKeys.Enter):
selectedItem, _ := m.modelList.GetSelectedItem()
models := m.models()
- var selectedModel client.ModelInfo
+ var selectedModel opencode.Model
for _, model := range models {
if model.Name == string(selectedItem) {
selectedModel = model
@@ -119,8 +119,8 @@ func (m *modelDialog) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, cmd
}
-func (m *modelDialog) models() []client.ModelInfo {
- models := slices.SortedFunc(maps.Values(m.provider.Models), func(a, b client.ModelInfo) int {
+func (m *modelDialog) models() []opencode.Model {
+ models := slices.SortedFunc(maps.Values(m.provider.Models), func(a, b opencode.Model) int {
return strings.Compare(a.Name, b.Name)
})
return models
@@ -139,7 +139,7 @@ func (m *modelDialog) switchProvider(offset int) {
m.hScrollOffset = newOffset
m.provider = m.availableProviders[m.hScrollOffset]
m.modal.SetTitle(fmt.Sprintf("Select %s Model", m.provider.Name))
- m.setupModelsForProvider(m.provider.Id)
+ m.setupModelsForProvider(m.provider.ID)
}
func (m *modelDialog) View() string {
@@ -175,9 +175,9 @@ func (m *modelDialog) setupModelsForProvider(providerId string) {
m.modelList = list.NewStringList(modelNames, numVisibleModels, "No models available", true)
m.modelList.SetMaxWidth(maxDialogWidth)
- if m.app.Provider != nil && m.app.Model != nil && m.app.Provider.Id == providerId {
+ if m.app.Provider != nil && m.app.Model != nil && m.app.Provider.ID == providerId {
for i, model := range models {
- if model.Id == m.app.Model.Id {
+ if model.ID == m.app.Model.ID {
m.modelList.SetSelectedIndex(i)
break
}
@@ -200,7 +200,7 @@ func NewModelDialog(app *app.App) ModelDialog {
hScrollOffset := 0
if app.Provider != nil {
for i, provider := range availableProviders {
- if provider.Id == app.Provider.Id {
+ if provider.ID == app.Provider.ID {
currentProvider = provider
hScrollOffset = i
break
@@ -220,6 +220,6 @@ func NewModelDialog(app *app.App) ModelDialog {
),
}
- dialog.setupModelsForProvider(currentProvider.Id)
+ dialog.setupModelsForProvider(currentProvider.ID)
return dialog
}
diff --git a/packages/tui/internal/components/dialog/session.go b/packages/tui/internal/components/dialog/session.go
index f38f37bf5..6f18dba0e 100644
--- a/packages/tui/internal/components/dialog/session.go
+++ b/packages/tui/internal/components/dialog/session.go
@@ -8,6 +8,7 @@ import (
tea "github.com/charmbracelet/bubbletea/v2"
"github.com/muesli/reflow/truncate"
+ "github.com/sst/opencode-sdk-go"
"github.com/sst/opencode/internal/app"
"github.com/sst/opencode/internal/components/list"
"github.com/sst/opencode/internal/components/modal"
@@ -16,7 +17,6 @@ import (
"github.com/sst/opencode/internal/styles"
"github.com/sst/opencode/internal/theme"
"github.com/sst/opencode/internal/util"
- "github.com/sst/opencode/pkg/client"
)
// SessionDialog interface for the session switching dialog
@@ -79,7 +79,7 @@ type sessionDialog struct {
width int
height int
modal *modal.Modal
- sessions []client.SessionInfo
+ sessions []opencode.Session
list list.List[sessionItem]
app *app.App
deleteConfirmation int // -1 means no confirmation, >= 0 means confirming deletion of session at this index
@@ -122,7 +122,7 @@ func (s *sessionDialog) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
s.updateListItems()
return nil
},
- s.deleteSession(sessionToDelete.Id),
+ s.deleteSession(sessionToDelete.ID),
)
} else {
// First press - enter delete confirmation mode
@@ -193,10 +193,10 @@ func (s *sessionDialog) Close() tea.Cmd {
func NewSessionDialog(app *app.App) SessionDialog {
sessions, _ := app.ListSessions(context.Background())
- var filteredSessions []client.SessionInfo
+ var filteredSessions []opencode.Session
var items []sessionItem
for _, sess := range sessions {
- if sess.ParentID != nil {
+ if sess.ParentID != "" {
continue
}
filteredSessions = append(filteredSessions, sess)
diff --git a/packages/tui/internal/components/status/status.go b/packages/tui/internal/components/status/status.go
index fb5ff8ced..fb44cbcb8 100644
--- a/packages/tui/internal/components/status/status.go
+++ b/packages/tui/internal/components/status/status.go
@@ -48,7 +48,7 @@ func (m statusComponent) logo() string {
Render(open + code + version)
}
-func formatTokensAndCost(tokens float32, contextWindow float32, cost float32) string {
+func formatTokensAndCost(tokens float64, contextWindow float64, cost float64) string {
// Format tokens in human-readable format (e.g., 110K, 1.2M)
var formattedTokens string
switch {
@@ -77,7 +77,7 @@ func formatTokensAndCost(tokens float32, contextWindow float32, cost float32) st
func (m statusComponent) View() string {
t := theme.CurrentTheme()
- if m.app.Session.Id == "" {
+ if m.app.Session.ID == "" {
return styles.NewStyle().
Background(t.Background()).
Width(m.width).
@@ -94,13 +94,13 @@ func (m statusComponent) View() string {
Render(m.app.Info.Path.Cwd)
sessionInfo := ""
- if m.app.Session.Id != "" {
- tokens := float32(0)
- cost := float32(0)
+ if m.app.Session.ID != "" {
+ tokens := float64(0)
+ cost := float64(0)
contextWindow := m.app.Model.Limit.Context
for _, message := range m.app.Messages {
- if message.Metadata.Assistant != nil {
+ if message.Metadata.Assistant.Cost > 0 {
cost += message.Metadata.Assistant.Cost
usage := message.Metadata.Assistant.Tokens
if usage.Output > 0 {