mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-22 18:24:21 +01:00
feat: toggle tool details visible
This commit is contained in:
@@ -202,6 +202,7 @@ export namespace Config {
|
|||||||
session_interrupt: z.string().optional().default("esc").describe("Interrupt current session"),
|
session_interrupt: z.string().optional().default("esc").describe("Interrupt current session"),
|
||||||
session_compact: z.string().optional().default("<leader>c").describe("Compact the session"),
|
session_compact: z.string().optional().default("<leader>c").describe("Compact the session"),
|
||||||
tool_details: z.string().optional().default("<leader>d").describe("Toggle tool details"),
|
tool_details: z.string().optional().default("<leader>d").describe("Toggle tool details"),
|
||||||
|
thinking_blocks: z.string().optional().default("<leader>b").describe("Toggle thinking blocks"),
|
||||||
model_list: z.string().optional().default("<leader>m").describe("List available models"),
|
model_list: z.string().optional().default("<leader>m").describe("List available models"),
|
||||||
theme_list: z.string().optional().default("<leader>t").describe("List available themes"),
|
theme_list: z.string().optional().default("<leader>t").describe("List available themes"),
|
||||||
file_list: z.string().optional().default("<leader>f").describe("List files"),
|
file_list: z.string().optional().default("<leader>f").describe("List files"),
|
||||||
|
|||||||
@@ -1007,7 +1007,7 @@ export namespace Session {
|
|||||||
async process(stream: StreamTextResult<Record<string, AITool>, never>) {
|
async process(stream: StreamTextResult<Record<string, AITool>, never>) {
|
||||||
try {
|
try {
|
||||||
let currentText: MessageV2.TextPart | undefined
|
let currentText: MessageV2.TextPart | undefined
|
||||||
// let reasoningMap: Record<string, MessageV2.ReasoningPart> = {}
|
let reasoningMap: Record<string, MessageV2.ReasoningPart> = {}
|
||||||
|
|
||||||
for await (const value of stream.fullStream) {
|
for await (const value of stream.fullStream) {
|
||||||
log.info("part", {
|
log.info("part", {
|
||||||
@@ -1017,7 +1017,6 @@ export namespace Session {
|
|||||||
case "start":
|
case "start":
|
||||||
break
|
break
|
||||||
|
|
||||||
/*
|
|
||||||
case "reasoning-start":
|
case "reasoning-start":
|
||||||
if (value.id in reasoningMap) {
|
if (value.id in reasoningMap) {
|
||||||
continue
|
continue
|
||||||
@@ -1055,7 +1054,6 @@ export namespace Session {
|
|||||||
delete reasoningMap[value.id]
|
delete reasoningMap[value.id]
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
*/
|
|
||||||
|
|
||||||
case "tool-input-start":
|
case "tool-input-start":
|
||||||
const part = await updatePart({
|
const part = await updatePart({
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ type State struct {
|
|||||||
MessagesRight bool `toml:"messages_right"`
|
MessagesRight bool `toml:"messages_right"`
|
||||||
SplitDiff bool `toml:"split_diff"`
|
SplitDiff bool `toml:"split_diff"`
|
||||||
MessageHistory []Prompt `toml:"message_history"`
|
MessageHistory []Prompt `toml:"message_history"`
|
||||||
|
ShowToolDetails *bool `toml:"show_tool_details"`
|
||||||
|
ShowThinkingBlocks *bool `toml:"show_thinking_blocks"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewState() *State {
|
func NewState() *State {
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ const (
|
|||||||
SessionCompactCommand CommandName = "session_compact"
|
SessionCompactCommand CommandName = "session_compact"
|
||||||
SessionExportCommand CommandName = "session_export"
|
SessionExportCommand CommandName = "session_export"
|
||||||
ToolDetailsCommand CommandName = "tool_details"
|
ToolDetailsCommand CommandName = "tool_details"
|
||||||
|
ThinkingBlocksCommand CommandName = "thinking_blocks"
|
||||||
ModelListCommand CommandName = "model_list"
|
ModelListCommand CommandName = "model_list"
|
||||||
AgentListCommand CommandName = "agent_list"
|
AgentListCommand CommandName = "agent_list"
|
||||||
ModelCycleRecentCommand CommandName = "model_cycle_recent"
|
ModelCycleRecentCommand CommandName = "model_cycle_recent"
|
||||||
@@ -245,6 +246,12 @@ func LoadFromConfig(config *opencode.Config) CommandRegistry {
|
|||||||
Keybindings: parseBindings("<leader>d"),
|
Keybindings: parseBindings("<leader>d"),
|
||||||
Trigger: []string{"details"},
|
Trigger: []string{"details"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: ThinkingBlocksCommand,
|
||||||
|
Description: "toggle thinking blocks",
|
||||||
|
Keybindings: parseBindings("<leader>b"),
|
||||||
|
Trigger: []string{"thinking"},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: ModelListCommand,
|
Name: ModelListCommand,
|
||||||
Description: "list models",
|
Description: "list models",
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ type MessagesComponent interface {
|
|||||||
HalfPageUp() (tea.Model, tea.Cmd)
|
HalfPageUp() (tea.Model, tea.Cmd)
|
||||||
HalfPageDown() (tea.Model, tea.Cmd)
|
HalfPageDown() (tea.Model, tea.Cmd)
|
||||||
ToolDetailsVisible() bool
|
ToolDetailsVisible() bool
|
||||||
|
ThinkingBlocksVisible() bool
|
||||||
GotoTop() (tea.Model, tea.Cmd)
|
GotoTop() (tea.Model, tea.Cmd)
|
||||||
GotoBottom() (tea.Model, tea.Cmd)
|
GotoBottom() (tea.Model, tea.Cmd)
|
||||||
CopyLastMessage() (tea.Model, tea.Cmd)
|
CopyLastMessage() (tea.Model, tea.Cmd)
|
||||||
@@ -41,20 +42,21 @@ type MessagesComponent interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type messagesComponent struct {
|
type messagesComponent struct {
|
||||||
width, height int
|
width, height int
|
||||||
app *app.App
|
app *app.App
|
||||||
header string
|
header string
|
||||||
viewport viewport.Model
|
viewport viewport.Model
|
||||||
clipboard []string
|
clipboard []string
|
||||||
cache *PartCache
|
cache *PartCache
|
||||||
loading bool
|
loading bool
|
||||||
showToolDetails bool
|
showToolDetails bool
|
||||||
rendering bool
|
showThinkingBlocks bool
|
||||||
dirty bool
|
rendering bool
|
||||||
tail bool
|
dirty bool
|
||||||
partCount int
|
tail bool
|
||||||
lineCount int
|
partCount int
|
||||||
selection *selection
|
lineCount int
|
||||||
|
selection *selection
|
||||||
}
|
}
|
||||||
|
|
||||||
type selection struct {
|
type selection struct {
|
||||||
@@ -94,6 +96,7 @@ func (s selection) coords(offset int) *selection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ToggleToolDetailsMsg struct{}
|
type ToggleToolDetailsMsg struct{}
|
||||||
|
type ToggleThinkingBlocksMsg struct{}
|
||||||
|
|
||||||
func (m *messagesComponent) Init() tea.Cmd {
|
func (m *messagesComponent) Init() tea.Cmd {
|
||||||
return tea.Batch(m.viewport.Init())
|
return tea.Batch(m.viewport.Init())
|
||||||
@@ -160,7 +163,12 @@ func (m *messagesComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
return m, m.renderView()
|
return m, m.renderView()
|
||||||
case ToggleToolDetailsMsg:
|
case ToggleToolDetailsMsg:
|
||||||
m.showToolDetails = !m.showToolDetails
|
m.showToolDetails = !m.showToolDetails
|
||||||
return m, m.renderView()
|
m.app.State.ShowToolDetails = &m.showToolDetails
|
||||||
|
return m, tea.Batch(m.renderView(), m.app.SaveState())
|
||||||
|
case ToggleThinkingBlocksMsg:
|
||||||
|
m.showThinkingBlocks = !m.showThinkingBlocks
|
||||||
|
m.app.State.ShowThinkingBlocks = &m.showThinkingBlocks
|
||||||
|
return m, tea.Batch(m.renderView(), m.app.SaveState())
|
||||||
case app.SessionLoadedMsg, app.SessionClearedMsg:
|
case app.SessionLoadedMsg, app.SessionClearedMsg:
|
||||||
m.cache.Clear()
|
m.cache.Clear()
|
||||||
m.tail = true
|
m.tail = true
|
||||||
@@ -561,32 +569,34 @@ func (m *messagesComponent) renderView() tea.Cmd {
|
|||||||
if reverted {
|
if reverted {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
text := "..."
|
if !m.showThinkingBlocks {
|
||||||
if part.Text != "" {
|
continue
|
||||||
text = part.Text
|
}
|
||||||
|
if part.Text != "" {
|
||||||
|
text := part.Text
|
||||||
|
content = renderText(
|
||||||
|
m.app,
|
||||||
|
message.Info,
|
||||||
|
text,
|
||||||
|
casted.ModelID,
|
||||||
|
m.showToolDetails,
|
||||||
|
width,
|
||||||
|
"",
|
||||||
|
true,
|
||||||
|
[]opencode.FilePart{},
|
||||||
|
[]opencode.AgentPart{},
|
||||||
|
)
|
||||||
|
content = lipgloss.PlaceHorizontal(
|
||||||
|
m.width,
|
||||||
|
lipgloss.Center,
|
||||||
|
content,
|
||||||
|
styles.WhitespaceStyle(t.Background()),
|
||||||
|
)
|
||||||
|
partCount++
|
||||||
|
lineCount += lipgloss.Height(content) + 1
|
||||||
|
blocks = append(blocks, content)
|
||||||
|
hasContent = true
|
||||||
}
|
}
|
||||||
content = renderText(
|
|
||||||
m.app,
|
|
||||||
message.Info,
|
|
||||||
text,
|
|
||||||
casted.ModelID,
|
|
||||||
m.showToolDetails,
|
|
||||||
width,
|
|
||||||
"",
|
|
||||||
true,
|
|
||||||
[]opencode.FilePart{},
|
|
||||||
[]opencode.AgentPart{},
|
|
||||||
)
|
|
||||||
content = lipgloss.PlaceHorizontal(
|
|
||||||
m.width,
|
|
||||||
lipgloss.Center,
|
|
||||||
content,
|
|
||||||
styles.WhitespaceStyle(t.Background()),
|
|
||||||
)
|
|
||||||
partCount++
|
|
||||||
lineCount += lipgloss.Height(content) + 1
|
|
||||||
blocks = append(blocks, content)
|
|
||||||
hasContent = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1006,6 +1016,10 @@ func (m *messagesComponent) ToolDetailsVisible() bool {
|
|||||||
return m.showToolDetails
|
return m.showToolDetails
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *messagesComponent) ThinkingBlocksVisible() bool {
|
||||||
|
return m.showThinkingBlocks
|
||||||
|
}
|
||||||
|
|
||||||
func (m *messagesComponent) GotoTop() (tea.Model, tea.Cmd) {
|
func (m *messagesComponent) GotoTop() (tea.Model, tea.Cmd) {
|
||||||
m.viewport.GotoTop()
|
m.viewport.GotoTop()
|
||||||
return m, nil
|
return m, nil
|
||||||
@@ -1202,11 +1216,23 @@ func NewMessagesComponent(app *app.App) MessagesComponent {
|
|||||||
vp.MouseWheelDelta = 4
|
vp.MouseWheelDelta = 4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default to showing tool details, hidden thinking blocks
|
||||||
|
showToolDetails := true
|
||||||
|
if app.State.ShowToolDetails != nil {
|
||||||
|
showToolDetails = *app.State.ShowToolDetails
|
||||||
|
}
|
||||||
|
|
||||||
|
showThinkingBlocks := false
|
||||||
|
if app.State.ShowThinkingBlocks != nil {
|
||||||
|
showThinkingBlocks = *app.State.ShowThinkingBlocks
|
||||||
|
}
|
||||||
|
|
||||||
return &messagesComponent{
|
return &messagesComponent{
|
||||||
app: app,
|
app: app,
|
||||||
viewport: vp,
|
viewport: vp,
|
||||||
showToolDetails: true,
|
showToolDetails: showToolDetails,
|
||||||
cache: NewPartCache(),
|
showThinkingBlocks: showThinkingBlocks,
|
||||||
tail: true,
|
cache: NewPartCache(),
|
||||||
|
tail: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1142,6 +1142,13 @@ func (a Model) executeCommand(command commands.Command) (tea.Model, tea.Cmd) {
|
|||||||
}
|
}
|
||||||
cmds = append(cmds, util.CmdHandler(chat.ToggleToolDetailsMsg{}))
|
cmds = append(cmds, util.CmdHandler(chat.ToggleToolDetailsMsg{}))
|
||||||
cmds = append(cmds, toast.NewInfoToast(message))
|
cmds = append(cmds, toast.NewInfoToast(message))
|
||||||
|
case commands.ThinkingBlocksCommand:
|
||||||
|
message := "Thinking blocks are now visible"
|
||||||
|
if a.messages.ThinkingBlocksVisible() {
|
||||||
|
message = "Thinking blocks are now hidden"
|
||||||
|
}
|
||||||
|
cmds = append(cmds, util.CmdHandler(chat.ToggleThinkingBlocksMsg{}))
|
||||||
|
cmds = append(cmds, toast.NewInfoToast(message))
|
||||||
case commands.ModelListCommand:
|
case commands.ModelListCommand:
|
||||||
modelDialog := dialog.NewModelDialog(a.app)
|
modelDialog := dialog.NewModelDialog(a.app)
|
||||||
a.modal = modelDialog
|
a.modal = modelDialog
|
||||||
|
|||||||
@@ -136,13 +136,14 @@
|
|||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
max-width: var(--md-tool-width);
|
max-width: var(--md-tool-width);
|
||||||
|
|
||||||
& > [data-component="assistant-reasoning-markdown"] {
|
[data-component="assistant-reasoning-markdown"] {
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
border: 1px solid var(--sl-color-blue-high);
|
border: 1px solid var(--sl-color-blue-high);
|
||||||
padding: 0.5rem calc(0.5rem + 3px);
|
padding: 0.5rem calc(0.5rem + 3px);
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
|
||||||
[data-component="copy-button"] {
|
[data-component="copy-button"] {
|
||||||
top: 0.5rem;
|
top: 0.5rem;
|
||||||
|
|||||||
@@ -152,18 +152,23 @@ export function Part(props: PartProps) {
|
|||||||
)}
|
)}
|
||||||
{` | ${props.message.modelID}`}
|
{` | ${props.message.modelID}`}
|
||||||
{props.message.mode && (
|
{props.message.mode && (
|
||||||
<span style={{ "font-weight": "bold", color: "var(--sl-color-accent)" }}>
|
<span style={{ color: "var(--sl-color-accent)" }}>{` | ${props.message.mode}`}</span>
|
||||||
{` | ${props.message.mode}`}
|
|
||||||
</span>
|
|
||||||
)}
|
)}
|
||||||
</Footer>
|
</Footer>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{props.message.role === "assistant" && props.part.type === "reasoning" && (
|
{props.message.role === "assistant" && props.part.type === "reasoning" && (
|
||||||
<div data-component="assistant-reasoning">
|
<div data-component="tool">
|
||||||
<div data-component="assistant-reasoning-markdown">
|
<div data-component="tool-title">
|
||||||
<ContentMarkdown expand={props.last} text={props.part.text || "Thinking..."} />
|
<span data-slot="name">Thinking</span>
|
||||||
|
</div>
|
||||||
|
<div data-component="assistant-reasoning">
|
||||||
|
<ResultsButton showCopy="Show details" hideCopy="Hide details">
|
||||||
|
<div data-component="assistant-reasoning-markdown">
|
||||||
|
<ContentMarkdown expand text={props.part.text || "Thinking..."} />
|
||||||
|
</div>
|
||||||
|
</ResultsButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -182,9 +187,7 @@ export function Part(props: PartProps) {
|
|||||||
)}
|
)}
|
||||||
{` | ${props.message.modelID}`}
|
{` | ${props.message.modelID}`}
|
||||||
{props.message.mode && (
|
{props.message.mode && (
|
||||||
<span style={{ "font-weight": "bold", color: "var(--sl-color-accent)" }}>
|
<span style={{ color: "var(--sl-color-accent)" }}>{` | ${props.message.mode}`}</span>
|
||||||
{` | ${props.message.mode}`}
|
|
||||||
</span>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user