From 2fc91001f4e6c6f463ae28a7d08eab473e840451 Mon Sep 17 00:00:00 2001 From: Kenn Costales Date: Fri, 15 Aug 2025 22:03:23 +0800 Subject: [PATCH] feat: add configurable paste summary thresholds --- packages/opencode/src/config/config.ts | 10 ++++ packages/sdk/go/config.go | 50 ++++++++++++++++++- packages/sdk/js/src/gen/types.gen.ts | 6 +++ .../tui/internal/components/chat/editor.go | 16 +++++- 4 files changed, 78 insertions(+), 4 deletions(-) diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 2041ac35f543..893b7877b50b 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -463,6 +463,16 @@ export namespace Config { .optional(), }) .optional(), + editor: z + .object({ + summary_thresholds: z + .object({ + lines: z.number().min(1).optional(), + chars: z.number().min(1).optional(), + }) + .optional(), + }) + .optional(), }) .optional(), }) diff --git a/packages/sdk/go/config.go b/packages/sdk/go/config.go index 59db54b954dc..70b62bebbdeb 100644 --- a/packages/sdk/go/config.go +++ b/packages/sdk/go/config.go @@ -693,14 +693,16 @@ func (r configCommandJSON) RawJSON() string { } type ConfigExperimental struct { - Hook ConfigExperimentalHook `json:"hook"` - JSON configExperimentalJSON `json:"-"` + Hook ConfigExperimentalHook `json:"hook"` + Editor ConfigExperimentalEditor `json:"editor"` + JSON configExperimentalJSON `json:"-"` } // configExperimentalJSON contains the JSON metadata for the struct // [ConfigExperimental] type configExperimentalJSON struct { Hook apijson.Field + Editor apijson.Field raw string ExtraFields map[string]apijson.Field } @@ -782,6 +784,50 @@ func (r configExperimentalHookSessionCompletedJSON) RawJSON() string { return r.raw } +type ConfigExperimentalEditor struct { + SummaryThresholds ConfigExperimentalEditorSummaryThresholds `json:"summary_thresholds"` + JSON configExperimentalEditorJSON `json:"-"` +} + +// configExperimentalEditorJSON contains the JSON metadata for the struct +// [ConfigExperimentalEditor] +type configExperimentalEditorJSON struct { + SummaryThresholds apijson.Field + raw string + ExtraFields map[string]apijson.Field +} + +func (r *ConfigExperimentalEditor) UnmarshalJSON(data []byte) (err error) { + return apijson.UnmarshalRoot(data, r) +} + +func (r configExperimentalEditorJSON) RawJSON() string { + return r.raw +} + +type ConfigExperimentalEditorSummaryThresholds struct { + Lines int64 `json:"lines"` + Chars int64 `json:"chars"` + JSON configExperimentalEditorSummaryThresholdsJSON `json:"-"` +} + +// configExperimentalEditorSummaryThresholdsJSON contains the JSON metadata for the struct +// [ConfigExperimentalEditorSummaryThresholds] +type configExperimentalEditorSummaryThresholdsJSON struct { + Lines apijson.Field + Chars apijson.Field + raw string + ExtraFields map[string]apijson.Field +} + +func (r *ConfigExperimentalEditorSummaryThresholds) UnmarshalJSON(data []byte) (err error) { + return apijson.UnmarshalRoot(data, r) +} + +func (r configExperimentalEditorSummaryThresholdsJSON) RawJSON() string { + return r.raw +} + type ConfigFormatter struct { Command []string `json:"command"` Disabled bool `json:"disabled"` diff --git a/packages/sdk/js/src/gen/types.gen.ts b/packages/sdk/js/src/gen/types.gen.ts index 434606d861eb..9804b46f42d6 100644 --- a/packages/sdk/js/src/gen/types.gen.ts +++ b/packages/sdk/js/src/gen/types.gen.ts @@ -761,6 +761,12 @@ export type Config = { } }> } + editor?: { + summary_thresholds?: { + lines?: number + chars?: number + } + } } } diff --git a/packages/tui/internal/components/chat/editor.go b/packages/tui/internal/components/chat/editor.go index 0c52ca84ca9d..c54f1ee48ff2 100644 --- a/packages/tui/internal/components/chat/editor.go +++ b/packages/tui/internal/components/chat/editor.go @@ -652,8 +652,20 @@ func (m *editorComponent) shouldSummarizePastedText(text string) bool { lineCount := len(lines) charCount := len(text) - // Consider text long if it has more than 3 lines or more than 150 characters - return lineCount > 3 || charCount > 150 + // Default thresholds + linesThreshold := int64(3) + charsThreshold := int64(150) + + // Override with config if provided + if m.app.Config != nil && m.app.Config.Experimental.Editor.SummaryThresholds.Lines > 0 { + linesThreshold = m.app.Config.Experimental.Editor.SummaryThresholds.Lines + } + if m.app.Config != nil && m.app.Config.Experimental.Editor.SummaryThresholds.Chars > 0 { + charsThreshold = m.app.Config.Experimental.Editor.SummaryThresholds.Chars + } + + // Consider text long if it exceeds the thresholds + return lineCount > int(linesThreshold) || charCount > int(charsThreshold) } // handleLongPaste handles long pasted text by creating a summary attachment