Skip to content

Context Window Warning #152

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
May 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 31 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,29 @@ OpenCode looks for configuration in the following locations:
- `$XDG_CONFIG_HOME/opencode/.opencode.json`
- `./.opencode.json` (local directory)

### Auto Compact Feature

OpenCode includes an auto compact feature that automatically summarizes your conversation when it approaches the model's context window limit. When enabled (default setting), this feature:

- Monitors token usage during your conversation
- Automatically triggers summarization when usage reaches 95% of the model's context window
- Creates a new session with the summary, allowing you to continue your work without losing context
- Helps prevent "out of context" errors that can occur with long conversations

You can enable or disable this feature in your configuration file:

```json
{
"autoCompact": true // default is true
}
```

### Environment Variables

You can configure OpenCode using environment variables:

| Environment Variable | Purpose |
|----------------------------|--------------------------------------------------------|
| -------------------------- | ------------------------------------------------------ |
| `ANTHROPIC_API_KEY` | For Claude models |
| `OPENAI_API_KEY` | For OpenAI models |
| `GEMINI_API_KEY` | For Google Gemini models |
Expand All @@ -79,7 +96,6 @@ You can configure OpenCode using environment variables:
| `AZURE_OPENAI_API_KEY` | For Azure OpenAI models (optional when using Entra ID) |
| `AZURE_OPENAI_API_VERSION` | For Azure OpenAI models |


### Configuration File Structure

```json
Expand Down Expand Up @@ -134,7 +150,8 @@ You can configure OpenCode using environment variables:
}
},
"debug": false,
"debugLSP": false
"debugLSP": false,
"autoCompact": true
}
```

Expand Down Expand Up @@ -327,9 +344,11 @@ OpenCode supports custom commands that can be created by users to quickly send p
Custom commands are predefined prompts stored as Markdown files in one of three locations:

1. **User Commands** (prefixed with `user:`):

```
$XDG_CONFIG_HOME/opencode/commands/
```

(typically `~/.config/opencode/commands/` on Linux/macOS)

or
Expand Down Expand Up @@ -382,6 +401,15 @@ This creates a command with ID `user:git:commit`.

The content of the command file will be sent as a message to the AI assistant.

### Built-in Commands

OpenCode includes several built-in commands:

| Command | Description |
| ------------------ | --------------------------------------------------------------------------------------------------- |
| Initialize Project | Creates or updates the OpenCode.md memory file with project-specific information |
| Compact Session | Manually triggers the summarization of the current session, creating a new session with the summary |

## MCP (Model Context Protocol)

OpenCode implements the Model Context Protocol (MCP) to extend its capabilities through external tools. MCP provides a standardized way for the AI assistant to interact with external services and tools.
Expand Down
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ func setupSubscriptions(app *app.App, parentCtx context.Context) (chan tea.Msg,
setupSubscriber(ctx, &wg, "sessions", app.Sessions.Subscribe, ch)
setupSubscriber(ctx, &wg, "messages", app.Messages.Subscribe, ch)
setupSubscriber(ctx, &wg, "permissions", app.Permissions.Subscribe, ch)
setupSubscriber(ctx, &wg, "coderAgent", app.CoderAgent.Subscribe, ch)

cleanupFunc := func() {
logging.Info("Cancelling all subscriptions")
Expand Down
17 changes: 14 additions & 3 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ type MCPServer struct {
type AgentName string

const (
AgentCoder AgentName = "coder"
AgentTask AgentName = "task"
AgentTitle AgentName = "title"
AgentCoder AgentName = "coder"
AgentSummarizer AgentName = "summarizer"
AgentTask AgentName = "task"
AgentTitle AgentName = "title"
)

// Agent defines configuration for different LLM models and their token limits.
Expand Down Expand Up @@ -84,6 +85,7 @@ type Config struct {
DebugLSP bool `json:"debugLSP,omitempty"`
ContextPaths []string `json:"contextPaths,omitempty"`
TUI TUIConfig `json:"tui"`
AutoCompact bool `json:"autoCompact,omitempty"`
}

// Application constants
Expand Down Expand Up @@ -213,6 +215,7 @@ func setDefaults(debug bool) {
viper.SetDefault("data.directory", defaultDataDirectory)
viper.SetDefault("contextPaths", defaultContextPaths)
viper.SetDefault("tui.theme", "opencode")
viper.SetDefault("autoCompact", true)

if debug {
viper.SetDefault("debug", true)
Expand Down Expand Up @@ -262,6 +265,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.summarizer.model", models.Claude37Sonnet)
viper.SetDefault("agents.task.model", models.Claude37Sonnet)
viper.SetDefault("agents.title.model", models.Claude37Sonnet)
return
Expand All @@ -270,6 +274,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.summarizer.model", models.GPT41)
viper.SetDefault("agents.task.model", models.GPT41Mini)
viper.SetDefault("agents.title.model", models.GPT41Mini)
return
Expand All @@ -278,6 +283,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.summarizer.model", models.Gemini25)
viper.SetDefault("agents.task.model", models.Gemini25Flash)
viper.SetDefault("agents.title.model", models.Gemini25Flash)
return
Expand All @@ -286,6 +292,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.summarizer.model", models.QWENQwq)
viper.SetDefault("agents.task.model", models.QWENQwq)
viper.SetDefault("agents.title.model", models.QWENQwq)
return
Expand All @@ -294,6 +301,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.summarizer.model", models.OpenRouterClaude37Sonnet)
viper.SetDefault("agents.task.model", models.OpenRouterClaude37Sonnet)
viper.SetDefault("agents.title.model", models.OpenRouterClaude35Haiku)
return
Expand All @@ -302,6 +310,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.summarizer.model", models.XAIGrok3Beta)
viper.SetDefault("agents.task.model", models.XAIGrok3Beta)
viper.SetDefault("agents.title.model", models.XAiGrok3MiniFastBeta)
return
Expand All @@ -310,6 +319,7 @@ func setProviderDefaults() {
// AWS Bedrock configuration
if hasAWSCredentials() {
viper.SetDefault("agents.coder.model", models.BedrockClaude37Sonnet)
viper.SetDefault("agents.summarizer.model", models.BedrockClaude37Sonnet)
viper.SetDefault("agents.task.model", models.BedrockClaude37Sonnet)
viper.SetDefault("agents.title.model", models.BedrockClaude37Sonnet)
return
Expand All @@ -318,6 +328,7 @@ func setProviderDefaults() {
// Azure OpenAI configuration
if os.Getenv("AZURE_OPENAI_ENDPOINT") != "" {
viper.SetDefault("agents.coder.model", models.AzureGPT41)
viper.SetDefault("agents.summarizer.model", models.AzureGPT41)
viper.SetDefault("agents.task.model", models.AzureGPT41Mini)
viper.SetDefault("agents.title.model", models.AzureGPT41Mini)
return
Expand Down
8 changes: 3 additions & 5 deletions internal/llm/agent/agent-tool.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ func (b *agentTool) Run(ctx context.Context, call tools.ToolCall) (tools.ToolRes
return tools.ToolResponse{}, fmt.Errorf("error generating agent: %s", err)
}
result := <-done
if result.Err() != nil {
return tools.ToolResponse{}, fmt.Errorf("error generating agent: %s", result.Err())
if result.Error != nil {
return tools.ToolResponse{}, fmt.Errorf("error generating agent: %s", result.Error)
}

response := result.Response()
response := result.Message
if response.Role != message.Assistant {
return tools.NewTextErrorResponse("no response"), nil
}
Expand All @@ -88,8 +88,6 @@ func (b *agentTool) Run(ctx context.Context, call tools.ToolCall) (tools.ToolRes
}

parentSession.Cost += updatedSession.Cost
parentSession.PromptTokens += updatedSession.PromptTokens
parentSession.CompletionTokens += updatedSession.CompletionTokens

_, err = b.sessions.Save(ctx, parentSession)
if err != nil {
Expand Down
Loading