From e1ac2df3fbdaeabc35dffd837bc12467b9882164 Mon Sep 17 00:00:00 2001 From: Ollie Agent Date: Sun, 16 Aug 2026 11:31:31 +0200 Subject: [PATCH] Lower tool output cap and add Markdown parsing --- cmd/olliesrv/internal/agent/loop.go | 4 ++-- go.mod | 3 +++ go.sum | 2 ++ tools/codeintel/internal/codeintel/codeintel.go | 4 +++- tools/codeintel/internal/codeintel/query_test.go | 14 +++++++++++++- 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/cmd/olliesrv/internal/agent/loop.go b/cmd/olliesrv/internal/agent/loop.go index a596641..b96b1c1 100644 --- a/cmd/olliesrv/internal/agent/loop.go +++ b/cmd/olliesrv/internal/agent/loop.go @@ -746,12 +746,12 @@ func contextBudget(ctx context.Context, b backend.Backend) int { // Truncation stack (from outer to inner): // - Server 10MB (toolsrv/shell.go limitedWriter): OOM safety. Prevents runaway // process output from exhausting memory. Well above model limit. -// - Agent 128KB (this constant): The model-facing cap. Applied in two places: +// - Agent 32KB (this constant): The model-facing cap. Applied in two places: // streaming path (caps real-time chunks sent to UI) and post-hoc (caps stored // result). Both use this constant — it's one policy, two enforcement points. // - Detach 64KB ring (toolsrv/detach.go): Separate system for background // processes. Unrelated to the model context. -const defaultToolResultMaxBytes = 131072 +const defaultToolResultMaxBytes = 32 * 1024 // MemoryTier classifies how long a tool result stays in the hot message list. type MemoryTier int diff --git a/go.mod b/go.mod index 387f0ec..7431dce 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/tree-sitter/tree-sitter-go v0.25.0 github.com/tree-sitter/tree-sitter-javascript v0.25.0 github.com/tree-sitter/tree-sitter-json v0.24.8 + github.com/tree-sitter/tree-sitter-markdown v0.0.0-00010101000000-000000000000 github.com/tree-sitter/tree-sitter-php v0.24.2 github.com/tree-sitter/tree-sitter-python v0.25.0 github.com/tree-sitter/tree-sitter-rust v0.24.2 @@ -31,3 +32,5 @@ require ( ) replace ollie/virtfs => ./virtfs + +replace github.com/tree-sitter/tree-sitter-markdown => github.com/tree-sitter-grammars/tree-sitter-markdown v0.3.2 diff --git a/go.sum b/go.sum index bbe26bc..ead31bc 100644 --- a/go.sum +++ b/go.sum @@ -37,6 +37,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tree-sitter-grammars/tree-sitter-markdown v0.3.2 h1:hQhxY9y3XYZHA2JOnhhvKUHtMBBn0vOl7iF4lbBxKzE= +github.com/tree-sitter-grammars/tree-sitter-markdown v0.3.2/go.mod h1:iR5v9x7eHV+ZrDVnyBhaMXArJ/Mtj3bSqs/xWqPtnIg= github.com/tree-sitter-grammars/tree-sitter-yaml v0.7.2 h1:Mmr9LYGTdr+8iD3ZEK1+j2FKZtY1Jt3y5Wq9dedgwfs= github.com/tree-sitter-grammars/tree-sitter-yaml v0.7.2/go.mod h1:tOZ8GmiIfLySKNOX58+PV2mvjFJdfciksfwotcELKbg= github.com/tree-sitter/go-tree-sitter v0.25.0 h1:sx6kcg8raRFCvc9BnXglke6axya12krCJF5xJ2sftRU= diff --git a/tools/codeintel/internal/codeintel/codeintel.go b/tools/codeintel/internal/codeintel/codeintel.go index d9406ff..f42df6b 100644 --- a/tools/codeintel/internal/codeintel/codeintel.go +++ b/tools/codeintel/internal/codeintel/codeintel.go @@ -14,6 +14,7 @@ import ( golang "github.com/tree-sitter/tree-sitter-go/bindings/go" javascript "github.com/tree-sitter/tree-sitter-javascript/bindings/go" jsonlang "github.com/tree-sitter/tree-sitter-json/bindings/go" + markdown "github.com/tree-sitter/tree-sitter-markdown/bindings/go" php "github.com/tree-sitter/tree-sitter-php/bindings/go" python "github.com/tree-sitter/tree-sitter-python/bindings/go" rust "github.com/tree-sitter/tree-sitter-rust/bindings/go" @@ -37,6 +38,7 @@ var languages = []Language{ {"cpp", []string{".cc", ".cpp", ".cxx", ".hpp", ".hxx"}, ts.NewLanguage(cpp.Language())}, {"json", []string{".json"}, ts.NewLanguage(jsonlang.Language())}, {"yaml", []string{".yaml", ".yml"}, ts.NewLanguage(yaml.Language())}, + {"markdown", []string{".md", ".markdown"}, ts.NewLanguage(markdown.Language())}, {"php", []string{".php"}, ts.NewLanguage(php.LanguagePHP())}, } @@ -121,7 +123,7 @@ func Files(root string) ([]File, error) { func Text(n *ts.Node, source []byte) string { return n.Utf8Text(source) } func Line(n *ts.Node) int { return int(n.StartPosition().Row) + 1 } func SymbolKinds() map[string]bool { - return map[string]bool{"function_declaration": true, "method_declaration": true, "func_literal": true, "type_declaration": true, "type_spec": true, "class_declaration": true, "class_definition": true, "struct_item": true, "enum_item": true, "interface_declaration": true, "namespace_definition": true, "function_definition": true, "function_item": true, "const_declaration": true, "var_declaration": true, "lexical_declaration": true, "variable_declaration": true, "import_declaration": true, "use_declaration": true, "callable_declaration": true, "property_declaration": true} + return map[string]bool{"function_declaration": true, "method_declaration": true, "func_literal": true, "type_declaration": true, "type_spec": true, "class_declaration": true, "class_definition": true, "struct_item": true, "enum_item": true, "interface_declaration": true, "namespace_definition": true, "function_definition": true, "function_item": true, "const_declaration": true, "var_declaration": true, "lexical_declaration": true, "variable_declaration": true, "import_declaration": true, "use_declaration": true, "callable_declaration": true, "property_declaration": true, "atx_heading": true, "setext_heading": true} } func Walk(n *ts.Node, fn func(*ts.Node)) { fn(n) diff --git a/tools/codeintel/internal/codeintel/query_test.go b/tools/codeintel/internal/codeintel/query_test.go index 43f7a0b..ea36883 100644 --- a/tools/codeintel/internal/codeintel/query_test.go +++ b/tools/codeintel/internal/codeintel/query_test.go @@ -21,7 +21,7 @@ func TestInterpolate(t *testing.T) { } func TestLanguageFor(t *testing.T) { - for _, tc := range []struct{ path, name, want string }{{"x.go", "", "go"}, {"x.tsx", "", "tsx"}, {"x.yml", "", "yaml"}, {"x.go", "python", "python"}, {"x.unknown", "", ""}} { + for _, tc := range []struct{ path, name, want string }{{"x.go", "", "go"}, {"x.tsx", "", "tsx"}, {"x.yml", "", "yaml"}, {"x.md", "", "markdown"}, {"x.go", "python", "python"}, {"x.unknown", "", ""}} { l, ok := LanguageFor(tc.path, tc.name) if (tc.want != "") != ok || ok && l.Name != tc.want { t.Errorf("LanguageFor(%q,%q)=%q,%v", tc.path, tc.name, l.Name, ok) @@ -55,3 +55,15 @@ func TestReplaceMatches(t *testing.T) { t.Fatalf("replace=%q err=%v", out, err) } } + +func TestMarkdownHeadings(t *testing.T) { + d := t.TempDir() + p := d + "/README.md" + if err := os.WriteFile(p, []byte("# Title\n\n## Section\ntext\n"), 0644); err != nil { + t.Fatal(err) + } + cs, err := Query(p, "", "(atx_heading) @heading") + if err != nil || len(cs) != 2 || cs[0].Line != 1 || cs[1].Line != 3 { + t.Fatalf("headings=%+v err=%v", cs, err) + } +}