summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authoradamdottv <[email protected]>2025-05-12 14:32:27 -0500
committeradamdottv <[email protected]>2025-05-12 14:32:27 -0500
commit36e5ae804e4bf0c96a0ce6cca90029e88c2da9b3 (patch)
treee4dd3910956376104c2b3996c245393bf625bc32
parentc9b90dd184084a2a3669db49717eb485c8861ee4 (diff)
downloadopencode-36e5ae804e4bf0c96a0ce6cca90029e88c2da9b3.tar.gz
opencode-36e5ae804e4bf0c96a0ce6cca90029e88c2da9b3.zip
chore: rename coder -> primary
-rw-r--r--README.md2
-rw-r--r--cmd/root.go6
-rw-r--r--cmd/schema/README.md5
-rw-r--r--cmd/schema/main.go2
-rw-r--r--internal/app/app.go10
-rw-r--r--internal/config/config.go22
-rw-r--r--internal/llm/agent/agent.go4
-rw-r--r--internal/llm/agent/tools.go2
-rw-r--r--internal/llm/prompt/primary.go (renamed from internal/llm/prompt/coder.go)10
-rw-r--r--internal/llm/prompt/prompt.go6
-rw-r--r--internal/pubsub/broker_test.go6
-rw-r--r--internal/tui/components/chat/editor.go4
-rw-r--r--internal/tui/components/chat/list.go4
-rw-r--r--internal/tui/components/core/status.go4
-rw-r--r--internal/tui/components/dialog/models.go4
-rw-r--r--internal/tui/page/chat.go8
-rw-r--r--internal/tui/tui.go10
-rw-r--r--opencode-schema.json2
18 files changed, 56 insertions, 55 deletions
diff --git a/README.md b/README.md
index b3eb37777..5db86c74b 100644
--- a/README.md
+++ b/README.md
@@ -105,7 +105,7 @@ You can configure OpenCode using environment variables:
}
},
"agents": {
- "coder": {
+ "primary": {
"model": "claude-3.7-sonnet",
"maxTokens": 5000
},
diff --git a/cmd/root.go b/cmd/root.go
index 1b8c4c574..d18c87854 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -86,7 +86,7 @@ to assist developers in writing, debugging, and understanding code directly from
app, err := app.New(ctx, conn)
if err != nil {
- slog.Error("Failed to create app: %v", err)
+ slog.Error("Failed to create app", "error", err)
return err
}
@@ -152,11 +152,11 @@ to assist developers in writing, debugging, and understanding code directly from
cleanup()
if err != nil {
- slog.Error("TUI error: %v", err)
+ slog.Error("TUI error", "error", err)
return fmt.Errorf("TUI error: %v", err)
}
- slog.Info("TUI exited with result: %v", result)
+ slog.Info("TUI exited", "result", result)
return nil
},
}
diff --git a/cmd/schema/README.md b/cmd/schema/README.md
index 93ebe9f03..e448ea0cb 100644
--- a/cmd/schema/README.md
+++ b/cmd/schema/README.md
@@ -46,7 +46,7 @@ Here's an example configuration that conforms to the schema:
}
},
"agents": {
- "coder": {
+ "primary": {
"model": "claude-3.7-sonnet",
"maxTokens": 5000,
"reasoningEffort": "medium"
@@ -61,4 +61,5 @@ Here's an example configuration that conforms to the schema:
}
}
}
-``` \ No newline at end of file
+```
+
diff --git a/cmd/schema/main.go b/cmd/schema/main.go
index 6340cb32f..f5786a7c0 100644
--- a/cmd/schema/main.go
+++ b/cmd/schema/main.go
@@ -274,7 +274,7 @@ func generateSchema() map[string]any {
// Add specific agent properties
agentProperties := map[string]any{}
knownAgents := []string{
- string(config.AgentCoder),
+ string(config.AgentPrimary),
string(config.AgentTask),
string(config.AgentTitle),
}
diff --git a/internal/app/app.go b/internal/app/app.go
index 283b311c8..d4110ac7c 100644
--- a/internal/app/app.go
+++ b/internal/app/app.go
@@ -29,7 +29,7 @@ type App struct {
Permissions permission.Service
Status status.Service
- CoderAgent agent.Service
+ PrimaryAgent agent.Service
LSPClients map[string]*lsp.Client
@@ -88,11 +88,11 @@ func New(ctx context.Context, conn *sql.DB) (*App, error) {
// Initialize LSP clients in the background
go app.initLSPClients(ctx)
- app.CoderAgent, err = agent.NewAgent(
- config.AgentCoder,
+ app.PrimaryAgent, err = agent.NewAgent(
+ config.AgentPrimary,
app.Sessions,
app.Messages,
- agent.CoderAgentTools(
+ agent.PrimaryAgentTools(
app.Permissions,
app.Sessions,
app.Messages,
@@ -101,7 +101,7 @@ func New(ctx context.Context, conn *sql.DB) (*App, error) {
),
)
if err != nil {
- slog.Error("Failed to create coder agent", err)
+ slog.Error("Failed to create primary agent", "error", err)
return nil, err
}
diff --git a/internal/config/config.go b/internal/config/config.go
index bb9ec447c..3f80456f6 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -36,9 +36,9 @@ type MCPServer struct {
type AgentName string
const (
- AgentCoder AgentName = "coder"
- AgentTask AgentName = "task"
- AgentTitle AgentName = "title"
+ AgentPrimary AgentName = "primary"
+ AgentTask AgentName = "task"
+ AgentTitle AgentName = "title"
)
// Agent defines configuration for different LLM models and their token limits.
@@ -238,7 +238,7 @@ func setProviderDefaults() {
// Anthropic configuration
if key := viper.GetString("providers.anthropic.apiKey"); strings.TrimSpace(key) != "" {
- viper.SetDefault("agents.coder.model", models.Claude37Sonnet)
+ viper.SetDefault("agents.primary.model", models.Claude37Sonnet)
viper.SetDefault("agents.task.model", models.Claude37Sonnet)
viper.SetDefault("agents.title.model", models.Claude37Sonnet)
return
@@ -246,7 +246,7 @@ func setProviderDefaults() {
// OpenAI configuration
if key := viper.GetString("providers.openai.apiKey"); strings.TrimSpace(key) != "" {
- viper.SetDefault("agents.coder.model", models.GPT41)
+ viper.SetDefault("agents.primary.model", models.GPT41)
viper.SetDefault("agents.task.model", models.GPT41Mini)
viper.SetDefault("agents.title.model", models.GPT41Mini)
return
@@ -254,7 +254,7 @@ func setProviderDefaults() {
// Google Gemini configuration
if key := viper.GetString("providers.gemini.apiKey"); strings.TrimSpace(key) != "" {
- viper.SetDefault("agents.coder.model", models.Gemini25)
+ viper.SetDefault("agents.primary.model", models.Gemini25)
viper.SetDefault("agents.task.model", models.Gemini25Flash)
viper.SetDefault("agents.title.model", models.Gemini25Flash)
return
@@ -262,7 +262,7 @@ func setProviderDefaults() {
// Groq configuration
if key := viper.GetString("providers.groq.apiKey"); strings.TrimSpace(key) != "" {
- viper.SetDefault("agents.coder.model", models.QWENQwq)
+ viper.SetDefault("agents.primary.model", models.QWENQwq)
viper.SetDefault("agents.task.model", models.QWENQwq)
viper.SetDefault("agents.title.model", models.QWENQwq)
return
@@ -270,7 +270,7 @@ func setProviderDefaults() {
// OpenRouter configuration
if key := viper.GetString("providers.openrouter.apiKey"); strings.TrimSpace(key) != "" {
- viper.SetDefault("agents.coder.model", models.OpenRouterClaude37Sonnet)
+ viper.SetDefault("agents.primary.model", models.OpenRouterClaude37Sonnet)
viper.SetDefault("agents.task.model", models.OpenRouterClaude37Sonnet)
viper.SetDefault("agents.title.model", models.OpenRouterClaude35Haiku)
return
@@ -278,7 +278,7 @@ func setProviderDefaults() {
// XAI configuration
if key := viper.GetString("providers.xai.apiKey"); strings.TrimSpace(key) != "" {
- viper.SetDefault("agents.coder.model", models.XAIGrok3Beta)
+ viper.SetDefault("agents.primary.model", models.XAIGrok3Beta)
viper.SetDefault("agents.task.model", models.XAIGrok3Beta)
viper.SetDefault("agents.title.model", models.XAiGrok3MiniFastBeta)
return
@@ -286,7 +286,7 @@ func setProviderDefaults() {
// AWS Bedrock configuration
if hasAWSCredentials() {
- viper.SetDefault("agents.coder.model", models.BedrockClaude37Sonnet)
+ viper.SetDefault("agents.primary.model", models.BedrockClaude37Sonnet)
viper.SetDefault("agents.task.model", models.BedrockClaude37Sonnet)
viper.SetDefault("agents.title.model", models.BedrockClaude37Sonnet)
return
@@ -294,7 +294,7 @@ func setProviderDefaults() {
// Azure OpenAI configuration
if os.Getenv("AZURE_OPENAI_ENDPOINT") != "" {
- viper.SetDefault("agents.coder.model", models.AzureGPT41)
+ viper.SetDefault("agents.primary.model", models.AzureGPT41)
viper.SetDefault("agents.task.model", models.AzureGPT41Mini)
viper.SetDefault("agents.title.model", models.AzureGPT41Mini)
return
diff --git a/internal/llm/agent/agent.go b/internal/llm/agent/agent.go
index 415fce3f0..e45411df7 100644
--- a/internal/llm/agent/agent.go
+++ b/internal/llm/agent/agent.go
@@ -74,7 +74,7 @@ func NewAgent(
}
var titleProvider provider.Provider
// Only generate titles for the coder agent
- if agentName == config.AgentCoder {
+ if agentName == config.AgentPrimary {
titleProvider, err = createAgentProvider(config.AgentTitle)
if err != nil {
return nil, err
@@ -673,7 +673,7 @@ func createAgentProvider(agentName config.AgentName) (provider.Provider, error)
provider.WithReasoningEffort(agentConfig.ReasoningEffort),
),
)
- } else if model.Provider == models.ProviderAnthropic && model.CanReason && agentName == config.AgentCoder {
+ } else if model.Provider == models.ProviderAnthropic && model.CanReason && agentName == config.AgentPrimary {
opts = append(
opts,
provider.WithAnthropicOptions(
diff --git a/internal/llm/agent/tools.go b/internal/llm/agent/tools.go
index b337efb59..7a23b723b 100644
--- a/internal/llm/agent/tools.go
+++ b/internal/llm/agent/tools.go
@@ -11,7 +11,7 @@ import (
"github.com/opencode-ai/opencode/internal/session"
)
-func CoderAgentTools(
+func PrimaryAgentTools(
permissions permission.Service,
sessions session.Service,
messages message.Service,
diff --git a/internal/llm/prompt/coder.go b/internal/llm/prompt/primary.go
index 639679328..c67e6d7a3 100644
--- a/internal/llm/prompt/coder.go
+++ b/internal/llm/prompt/primary.go
@@ -13,18 +13,18 @@ import (
"github.com/opencode-ai/opencode/internal/llm/tools"
)
-func CoderPrompt(provider models.ModelProvider) string {
- basePrompt := baseAnthropicCoderPrompt
+func PrimaryPrompt(provider models.ModelProvider) string {
+ basePrompt := baseAnthropicPrimaryPrompt
switch provider {
case models.ProviderOpenAI:
- basePrompt = baseOpenAICoderPrompt
+ basePrompt = baseOpenAIPrimaryPrompt
}
envInfo := getEnvironmentInfo()
return fmt.Sprintf("%s\n\n%s\n%s", basePrompt, envInfo, lspInformation())
}
-const baseOpenAICoderPrompt = `
+const baseOpenAIPrimaryPrompt = `
You are operating as and within the OpenCode CLI, a terminal-based agentic coding assistant built by OpenAI. It wraps OpenAI models to enable natural language interaction with a local codebase. You are expected to be precise, safe, and helpful.
You can:
@@ -71,7 +71,7 @@ You MUST adhere to the following criteria when executing the task:
- Remember the user does not see the full output of tools
`
-const baseAnthropicCoderPrompt = `You are OpenCode, an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.
+const baseAnthropicPrimaryPrompt = `You are OpenCode, an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.
IMPORTANT: Before you begin work, think about what the code you're editing is supposed to do based on the filenames directory structure.
diff --git a/internal/llm/prompt/prompt.go b/internal/llm/prompt/prompt.go
index 769fd51ab..660142320 100644
--- a/internal/llm/prompt/prompt.go
+++ b/internal/llm/prompt/prompt.go
@@ -15,8 +15,8 @@ import (
func GetAgentPrompt(agentName config.AgentName, provider models.ModelProvider) string {
basePrompt := ""
switch agentName {
- case config.AgentCoder:
- basePrompt = CoderPrompt(provider)
+ case config.AgentPrimary:
+ basePrompt = PrimaryPrompt(provider)
case config.AgentTitle:
basePrompt = TitlePrompt(provider)
case config.AgentTask:
@@ -25,7 +25,7 @@ func GetAgentPrompt(agentName config.AgentName, provider models.ModelProvider) s
basePrompt = "You are a helpful assistant"
}
- if agentName == config.AgentCoder || agentName == config.AgentTask {
+ if agentName == config.AgentPrimary || agentName == config.AgentTask {
// Add context from project-specific instruction files if they exist
contextContent := getContextFromPaths()
slog.Debug("Context content", "Context", contextContent)
diff --git a/internal/pubsub/broker_test.go b/internal/pubsub/broker_test.go
index 1a82011fc..b4caa98f3 100644
--- a/internal/pubsub/broker_test.go
+++ b/internal/pubsub/broker_test.go
@@ -51,12 +51,12 @@ func TestBrokerPublish(t *testing.T) {
ch := broker.Subscribe(ctx)
// Publish a message
- broker.Publish("created", "test message")
+ broker.Publish(EventTypeCreated, "test message")
// Verify message is received
select {
case event := <-ch:
- assert.Equal(t, "created", event.Type)
+ assert.Equal(t, EventTypeCreated, event.Type)
assert.Equal(t, "test message", event.Payload)
case <-time.After(100 * time.Millisecond):
t.Fatal("timeout waiting for message")
@@ -122,7 +122,7 @@ func TestBrokerConcurrency(t *testing.T) {
// Publish messages to all subscribers
for i := range numSubscribers {
- broker.Publish("created", i)
+ broker.Publish(EventTypeCreated, i)
}
// Wait for all subscribers to finish
diff --git a/internal/tui/components/chat/editor.go b/internal/tui/components/chat/editor.go
index 99991cdf7..e96e6df3d 100644
--- a/internal/tui/components/chat/editor.go
+++ b/internal/tui/components/chat/editor.go
@@ -124,7 +124,7 @@ func (m *editorCmp) Init() tea.Cmd {
}
func (m *editorCmp) send() tea.Cmd {
- if m.app.CoderAgent.IsSessionBusy(m.session.ID) {
+ if m.app.PrimaryAgent.IsSessionBusy(m.session.ID) {
status.Warn("Agent is working, please wait...")
return nil
}
@@ -189,7 +189,7 @@ func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, nil
}
if key.Matches(msg, editorMaps.OpenEditor) {
- if m.app.CoderAgent.IsSessionBusy(m.session.ID) {
+ if m.app.PrimaryAgent.IsSessionBusy(m.session.ID) {
status.Warn("Agent is working, please wait...")
return m, nil
}
diff --git a/internal/tui/components/chat/list.go b/internal/tui/components/chat/list.go
index bce6f50e1..bf72e74b5 100644
--- a/internal/tui/components/chat/list.go
+++ b/internal/tui/components/chat/list.go
@@ -170,7 +170,7 @@ func (m *messagesCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
func (m *messagesCmp) IsAgentWorking() bool {
- return m.app.CoderAgent.IsSessionBusy(m.session.ID)
+ return m.app.PrimaryAgent.IsSessionBusy(m.session.ID)
}
func formatTimeDifference(unixTime1, unixTime2 int64) string {
@@ -376,7 +376,7 @@ func (m *messagesCmp) help() string {
text := ""
- if m.app.CoderAgent.IsBusy() {
+ if m.app.PrimaryAgent.IsBusy() {
text += lipgloss.JoinHorizontal(
lipgloss.Left,
baseStyle.Foreground(t.TextMuted()).Bold(true).Render("press "),
diff --git a/internal/tui/components/core/status.go b/internal/tui/components/core/status.go
index d6612fed4..be2f39432 100644
--- a/internal/tui/components/core/status.go
+++ b/internal/tui/components/core/status.go
@@ -140,7 +140,7 @@ func formatTokensAndCost(tokens int64, contextWindow int64, cost float64) string
func (m statusCmp) View() string {
t := theme.CurrentTheme()
- modelID := config.Get().Agents[config.AgentCoder].Model
+ modelID := config.Get().Agents[config.AgentPrimary].Model
model := models.SupportedModels[modelID]
// Initialize the help widget
@@ -283,7 +283,7 @@ func (m statusCmp) model() string {
cfg := config.Get()
- coder, ok := cfg.Agents[config.AgentCoder]
+ coder, ok := cfg.Agents[config.AgentPrimary]
if !ok {
return "Unknown"
}
diff --git a/internal/tui/components/dialog/models.go b/internal/tui/components/dialog/models.go
index 9dc2fdffe..67c4fdfa1 100644
--- a/internal/tui/components/dialog/models.go
+++ b/internal/tui/components/dialog/models.go
@@ -283,7 +283,7 @@ func (m *modelDialogCmp) setupModels() {
func GetSelectedModel(cfg *config.Config) models.Model {
- agentCfg := cfg.Agents[config.AgentCoder]
+ agentCfg := cfg.Agents[config.AgentPrimary]
selectedModelId := agentCfg.Model
return models.SupportedModels[selectedModelId]
}
@@ -325,7 +325,7 @@ func findProviderIndex(providers []models.ModelProvider, provider models.ModelPr
func (m *modelDialogCmp) setupModelsForProvider(provider models.ModelProvider) {
cfg := config.Get()
- agentCfg := cfg.Agents[config.AgentCoder]
+ agentCfg := cfg.Agents[config.AgentPrimary]
selectedModelId := agentCfg.Model
m.provider = provider
diff --git a/internal/tui/page/chat.go b/internal/tui/page/chat.go
index b4984c511..fe71d6f7a 100644
--- a/internal/tui/page/chat.go
+++ b/internal/tui/page/chat.go
@@ -67,7 +67,7 @@ func (p *chatPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
case dialog.CommandRunCustomMsg:
// Check if the agent is busy before executing custom commands
- if p.app.CoderAgent.IsBusy() {
+ if p.app.PrimaryAgent.IsBusy() {
status.Warn("Agent is busy, please wait before executing a command...")
return p, nil
}
@@ -92,7 +92,7 @@ func (p *chatPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// Run compaction in background
go func(sessionID string) {
- err := p.app.CoderAgent.CompactSession(context.Background(), sessionID)
+ err := p.app.PrimaryAgent.CompactSession(context.Background(), sessionID)
if err != nil {
status.Error(fmt.Sprintf("Compaction failed: %v", err))
} else {
@@ -113,7 +113,7 @@ func (p *chatPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if p.session.ID != "" {
// Cancel the current session's generation process
// This allows users to interrupt long-running operations
- p.app.CoderAgent.Cancel(p.session.ID)
+ p.app.PrimaryAgent.Cancel(p.session.ID)
return p, nil
}
case key.Matches(msg, keyMap.ToggleTools):
@@ -158,7 +158,7 @@ func (p *chatPage) sendMessage(text string, attachments []message.Attachment) te
cmds = append(cmds, util.CmdHandler(chat.SessionSelectedMsg(newSession)))
}
- _, err := p.app.CoderAgent.Run(context.Background(), p.session.ID, text, attachments...)
+ _, err := p.app.PrimaryAgent.Run(context.Background(), p.session.ID, text, attachments...)
if err != nil {
status.Error(err.Error())
return nil
diff --git a/internal/tui/tui.go b/internal/tui/tui.go
index 84fbcfdea..a0430faf7 100644
--- a/internal/tui/tui.go
+++ b/internal/tui/tui.go
@@ -266,7 +266,7 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case dialog.ModelSelectedMsg:
a.showModelDialog = false
- model, err := a.app.CoderAgent.Update(config.AgentCoder, msg.Model.ID)
+ model, err := a.app.PrimaryAgent.Update(config.AgentPrimary, msg.Model.ID)
if err != nil {
status.Error(err.Error())
return a, nil
@@ -460,7 +460,7 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
a.showHelp = !a.showHelp
return a, nil
case key.Matches(msg, helpEsc):
- if a.app.CoderAgent.IsBusy() {
+ if a.app.PrimaryAgent.IsBusy() {
if a.showQuit {
return a, nil
}
@@ -574,7 +574,7 @@ func (a *appModel) RegisterCommand(cmd dialog.Command) {
func (a *appModel) moveToPage(pageID page.PageID) tea.Cmd {
// Allow navigating to logs page even when agent is busy
- if a.app.CoderAgent.IsBusy() && pageID != page.LogsPage {
+ if a.app.PrimaryAgent.IsBusy() && pageID != page.LogsPage {
// Don't move to other pages if the agent is busy
status.Warn("Agent is busy, please wait...")
return nil
@@ -641,7 +641,7 @@ func (a appModel) View() string {
}
- if !a.app.CoderAgent.IsBusy() {
+ if !a.app.PrimaryAgent.IsBusy() {
a.status.SetHelpWidgetMsg("ctrl+? help")
} else {
a.status.SetHelpWidgetMsg("? help")
@@ -658,7 +658,7 @@ func (a appModel) View() string {
if a.currentPage == page.LogsPage {
bindings = append(bindings, logsKeyReturnKey)
}
- if !a.app.CoderAgent.IsBusy() {
+ if !a.app.PrimaryAgent.IsBusy() {
bindings = append(bindings, helpEsc)
}
a.help.SetBindings(bindings)
diff --git a/opencode-schema.json b/opencode-schema.json
index e9665eab5..d6af65cf0 100644
--- a/opencode-schema.json
+++ b/opencode-schema.json
@@ -179,7 +179,7 @@
},
"description": "Agent configurations",
"properties": {
- "coder": {
+ "primary": {
"$ref": "#/definitions/agent"
},
"task": {