summaryrefslogtreecommitdiffhomepage
path: root/internal/llm/agent
diff options
context:
space:
mode:
authorKujtim Hoxha <[email protected]>2025-04-03 15:20:15 +0200
committerKujtim Hoxha <[email protected]>2025-04-03 17:23:41 +0200
commitcfdd687216799cb5b47f099f1e7cd5dd16b3bdd0 (patch)
treea822bfde1463a7080c0ea06dd17796d7a1617d3d /internal/llm/agent
parentafd9ad0560d76c2a6d161dad52553b10ff428905 (diff)
downloadopencode-cfdd687216799cb5b47f099f1e7cd5dd16b3bdd0.tar.gz
opencode-cfdd687216799cb5b47f099f1e7cd5dd16b3bdd0.zip
add initial lsp support
Diffstat (limited to 'internal/llm/agent')
-rw-r--r--internal/llm/agent/agent-tool.go2
-rw-r--r--internal/llm/agent/agent.go49
-rw-r--r--internal/llm/agent/coder.go13
-rw-r--r--internal/llm/agent/task.go2
4 files changed, 42 insertions, 24 deletions
diff --git a/internal/llm/agent/agent-tool.go b/internal/llm/agent/agent-tool.go
index a87f48339..bf5e31f8f 100644
--- a/internal/llm/agent/agent-tool.go
+++ b/internal/llm/agent/agent-tool.go
@@ -91,7 +91,7 @@ func (b *agentTool) Run(ctx context.Context, call tools.ToolCall) (tools.ToolRes
if err != nil {
return tools.NewTextErrorResponse(fmt.Sprintf("error: %s", err)), nil
}
- return tools.NewTextResponse(response.Content), nil
+ return tools.NewTextResponse(response.Content().String()), nil
}
func NewAgentTool(parentSessionID string, app *app.App) tools.BaseTool {
diff --git a/internal/llm/agent/agent.go b/internal/llm/agent/agent.go
index 06dbca4e8..cb123e78c 100644
--- a/internal/llm/agent/agent.go
+++ b/internal/llm/agent/agent.go
@@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"log"
+ "strings"
"sync"
"github.com/kujtimiihoxha/termai/internal/app"
@@ -33,8 +34,12 @@ func (c *agent) handleTitleGeneration(sessionID, content string) {
c.Context,
[]message.Message{
{
- Role: message.User,
- Content: content,
+ Role: message.User,
+ Parts: []message.ContentPart{
+ message.TextContent{
+ Text: content,
+ },
+ },
},
},
nil,
@@ -49,6 +54,8 @@ func (c *agent) handleTitleGeneration(sessionID, content string) {
}
if response.Content != "" {
session.Title = response.Content
+ session.Title = strings.TrimSpace(session.Title)
+ session.Title = strings.ReplaceAll(session.Title, "\n", " ")
c.Sessions.Save(session)
}
}
@@ -79,17 +86,18 @@ func (c *agent) processEvent(
) error {
switch event.Type {
case provider.EventThinkingDelta:
- assistantMsg.Thinking += event.Thinking
+ assistantMsg.AppendReasoningContent(event.Content)
return c.Messages.Update(*assistantMsg)
case provider.EventContentDelta:
- assistantMsg.Content += event.Content
+ assistantMsg.AppendContent(event.Content)
return c.Messages.Update(*assistantMsg)
case provider.EventError:
log.Println("error", event.Error)
return event.Error
case provider.EventComplete:
- assistantMsg.ToolCalls = event.Response.ToolCalls
+ assistantMsg.SetToolCalls(event.Response.ToolCalls)
+ assistantMsg.AddFinish(event.Response.FinishReason)
err := c.Messages.Update(*assistantMsg)
if err != nil {
return err
@@ -157,18 +165,21 @@ func (c *agent) handleToolExecution(
ctx context.Context,
assistantMsg message.Message,
) (*message.Message, error) {
- if len(assistantMsg.ToolCalls) == 0 {
+ if len(assistantMsg.ToolCalls()) == 0 {
return nil, nil
}
- toolResults, err := c.ExecuteTools(ctx, assistantMsg.ToolCalls, c.tools)
+ toolResults, err := c.ExecuteTools(ctx, assistantMsg.ToolCalls(), c.tools)
if err != nil {
return nil, err
}
-
+ parts := make([]message.ContentPart, 0)
+ for _, toolResult := range toolResults {
+ parts = append(parts, toolResult)
+ }
msg, err := c.Messages.Create(assistantMsg.SessionID, message.CreateMessageParams{
- Role: message.Tool,
- ToolResults: toolResults,
+ Role: message.Tool,
+ Parts: parts,
})
return &msg, err
@@ -185,8 +196,12 @@ func (c *agent) generate(sessionID string, content string) error {
}
userMsg, err := c.Messages.Create(sessionID, message.CreateMessageParams{
- Role: message.User,
- Content: content,
+ Role: message.User,
+ Parts: []message.ContentPart{
+ message.TextContent{
+ Text: content,
+ },
+ },
})
if err != nil {
return err
@@ -201,8 +216,8 @@ func (c *agent) generate(sessionID string, content string) error {
}
assistantMsg, err := c.Messages.Create(sessionID, message.CreateMessageParams{
- Role: message.Assistant,
- Content: "",
+ Role: message.Assistant,
+ Parts: []message.ContentPart{},
})
if err != nil {
return err
@@ -210,20 +225,20 @@ func (c *agent) generate(sessionID string, content string) error {
for event := range eventChan {
err = c.processEvent(sessionID, &assistantMsg, event)
if err != nil {
- assistantMsg.Finished = true
+ assistantMsg.AddFinish("error:" + err.Error())
c.Messages.Update(assistantMsg)
return err
}
}
msg, err := c.handleToolExecution(c.Context, assistantMsg)
- assistantMsg.Finished = true
+
c.Messages.Update(assistantMsg)
if err != nil {
return err
}
- if len(assistantMsg.ToolCalls) == 0 {
+ if len(assistantMsg.ToolCalls()) == 0 {
break
}
diff --git a/internal/llm/agent/coder.go b/internal/llm/agent/coder.go
index 38dfd2de1..d167ede99 100644
--- a/internal/llm/agent/coder.go
+++ b/internal/llm/agent/coder.go
@@ -44,20 +44,23 @@ func NewCoderAgent(app *app.App) (Agent, error) {
return nil, err
}
- mcpTools := GetMcpTools(app.Context)
+ otherTools := GetMcpTools(app.Context)
+ if len(app.LSPClients) > 0 {
+ otherTools = append(otherTools, tools.NewDiagnosticsTool(app.LSPClients))
+ }
return &coderAgent{
agent: &agent{
App: app,
tools: append(
[]tools.BaseTool{
tools.NewBashTool(),
- tools.NewEditTool(),
+ tools.NewEditTool(app.LSPClients),
tools.NewGlobTool(),
tools.NewGrepTool(),
tools.NewLsTool(),
- tools.NewViewTool(),
- tools.NewWriteTool(),
- }, mcpTools...,
+ tools.NewViewTool(app.LSPClients),
+ tools.NewWriteTool(app.LSPClients),
+ }, otherTools...,
),
model: model,
agent: agentProvider,
diff --git a/internal/llm/agent/task.go b/internal/llm/agent/task.go
index 9e0311ed1..97611e62b 100644
--- a/internal/llm/agent/task.go
+++ b/internal/llm/agent/task.go
@@ -34,7 +34,7 @@ func NewTaskAgent(app *app.App) (Agent, error) {
tools.NewGlobTool(),
tools.NewGrepTool(),
tools.NewLsTool(),
- tools.NewViewTool(),
+ tools.NewViewTool(app.LSPClients),
},
model: model,
agent: agentProvider,