brute 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/brute/agent_stream.rb +49 -0
- data/lib/brute/compactor.rb +105 -0
- data/lib/brute/doom_loop.rb +84 -0
- data/lib/brute/file_mutation_queue.rb +99 -0
- data/lib/brute/hooks.rb +84 -0
- data/lib/brute/middleware/base.rb +27 -0
- data/lib/brute/middleware/compaction_check.rb +56 -0
- data/lib/brute/middleware/doom_loop_detection.rb +33 -0
- data/lib/brute/middleware/llm_call.rb +28 -0
- data/lib/brute/middleware/reasoning_normalizer.rb +98 -0
- data/lib/brute/middleware/retry.rb +45 -0
- data/lib/brute/middleware/session_persistence.rb +29 -0
- data/lib/brute/middleware/token_tracking.rb +46 -0
- data/lib/brute/middleware/tool_error_tracking.rb +46 -0
- data/lib/brute/middleware/tracing.rb +34 -0
- data/lib/brute/orchestrator.rb +297 -0
- data/lib/brute/patches/anthropic_tool_role.rb +35 -0
- data/lib/brute/patches/buffer_nil_guard.rb +21 -0
- data/lib/brute/pipeline.rb +81 -0
- data/lib/brute/session.rb +86 -0
- data/lib/brute/snapshot_store.rb +49 -0
- data/lib/brute/system_prompt.rb +88 -0
- data/lib/brute/todo_store.rb +27 -0
- data/lib/brute/tools/delegate.rb +35 -0
- data/lib/brute/tools/fs_patch.rb +37 -0
- data/lib/brute/tools/fs_read.rb +37 -0
- data/lib/brute/tools/fs_remove.rb +31 -0
- data/lib/brute/tools/fs_search.rb +38 -0
- data/lib/brute/tools/fs_undo.rb +29 -0
- data/lib/brute/tools/fs_write.rb +26 -0
- data/lib/brute/tools/net_fetch.rb +37 -0
- data/lib/brute/tools/shell.rb +38 -0
- data/lib/brute/tools/todo_read.rb +15 -0
- data/lib/brute/tools/todo_write.rb +32 -0
- data/lib/brute.rb +121 -0
- metadata +101 -0
data/lib/brute.rb
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "llm"
|
|
4
|
+
require "timeout"
|
|
5
|
+
require "logger"
|
|
6
|
+
|
|
7
|
+
# Brute — a coding agent built on llm.rb
|
|
8
|
+
#
|
|
9
|
+
# Cross-cutting concerns are implemented as Rack-style middleware in a
|
|
10
|
+
# Pipeline that wraps every LLM call:
|
|
11
|
+
#
|
|
12
|
+
# Tracing → Retry → Session → Tokens → Compaction → ToolErrors → DoomLoop → Reasoning → [LLM Call]
|
|
13
|
+
#
|
|
14
|
+
module Brute
|
|
15
|
+
module Tools; end
|
|
16
|
+
module Hooks; end
|
|
17
|
+
module Middleware; end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Infrastructure
|
|
21
|
+
require_relative "brute/snapshot_store"
|
|
22
|
+
require_relative "brute/todo_store"
|
|
23
|
+
require_relative "brute/file_mutation_queue"
|
|
24
|
+
require_relative "brute/doom_loop"
|
|
25
|
+
require_relative "brute/hooks"
|
|
26
|
+
require_relative "brute/compactor"
|
|
27
|
+
require_relative "brute/system_prompt"
|
|
28
|
+
require_relative "brute/session"
|
|
29
|
+
require_relative "brute/pipeline"
|
|
30
|
+
require_relative "brute/agent_stream"
|
|
31
|
+
|
|
32
|
+
# Provider patches
|
|
33
|
+
require_relative "brute/patches/anthropic_tool_role"
|
|
34
|
+
require_relative "brute/patches/buffer_nil_guard"
|
|
35
|
+
|
|
36
|
+
# Middleware (Rack-style)
|
|
37
|
+
require_relative "brute/middleware/base"
|
|
38
|
+
require_relative "brute/middleware/llm_call"
|
|
39
|
+
require_relative "brute/middleware/retry"
|
|
40
|
+
require_relative "brute/middleware/doom_loop_detection"
|
|
41
|
+
require_relative "brute/middleware/token_tracking"
|
|
42
|
+
require_relative "brute/middleware/compaction_check"
|
|
43
|
+
require_relative "brute/middleware/session_persistence"
|
|
44
|
+
require_relative "brute/middleware/tracing"
|
|
45
|
+
require_relative "brute/middleware/tool_error_tracking"
|
|
46
|
+
require_relative "brute/middleware/reasoning_normalizer"
|
|
47
|
+
|
|
48
|
+
# Tools
|
|
49
|
+
require_relative "brute/tools/fs_read"
|
|
50
|
+
require_relative "brute/tools/fs_write"
|
|
51
|
+
require_relative "brute/tools/fs_patch"
|
|
52
|
+
require_relative "brute/tools/fs_remove"
|
|
53
|
+
require_relative "brute/tools/fs_search"
|
|
54
|
+
require_relative "brute/tools/fs_undo"
|
|
55
|
+
require_relative "brute/tools/shell"
|
|
56
|
+
require_relative "brute/tools/net_fetch"
|
|
57
|
+
require_relative "brute/tools/todo_write"
|
|
58
|
+
require_relative "brute/tools/todo_read"
|
|
59
|
+
require_relative "brute/tools/delegate"
|
|
60
|
+
|
|
61
|
+
# Orchestrator (depends on tools, middleware, and infrastructure)
|
|
62
|
+
require_relative "brute/orchestrator"
|
|
63
|
+
|
|
64
|
+
module Brute
|
|
65
|
+
VERSION = "0.1.0"
|
|
66
|
+
|
|
67
|
+
# The complete set of tools available to the agent.
|
|
68
|
+
TOOLS = [
|
|
69
|
+
Tools::FSRead,
|
|
70
|
+
Tools::FSWrite,
|
|
71
|
+
Tools::FSPatch,
|
|
72
|
+
Tools::FSRemove,
|
|
73
|
+
Tools::FSSearch,
|
|
74
|
+
Tools::FSUndo,
|
|
75
|
+
Tools::Shell,
|
|
76
|
+
Tools::NetFetch,
|
|
77
|
+
Tools::TodoWrite,
|
|
78
|
+
Tools::TodoRead,
|
|
79
|
+
Tools::Delegate,
|
|
80
|
+
].freeze
|
|
81
|
+
|
|
82
|
+
# Default provider, resolved from environment.
|
|
83
|
+
def self.provider
|
|
84
|
+
@provider ||= resolve_provider
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def self.provider=(p)
|
|
88
|
+
@provider = p
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Create a new orchestrator with sensible defaults.
|
|
92
|
+
def self.agent(cwd: Dir.pwd, tools: TOOLS, session: nil, reasoning: {}, **callbacks)
|
|
93
|
+
Orchestrator.new(
|
|
94
|
+
provider: provider,
|
|
95
|
+
tools: tools,
|
|
96
|
+
cwd: cwd,
|
|
97
|
+
session: session,
|
|
98
|
+
reasoning: reasoning,
|
|
99
|
+
**callbacks
|
|
100
|
+
)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def self.resolve_provider
|
|
104
|
+
if ENV["ANTHROPIC_API_KEY"]
|
|
105
|
+
LLM.anthropic(key: ENV["ANTHROPIC_API_KEY"]).tap { Patches::AnthropicToolRole.apply! }
|
|
106
|
+
elsif ENV["OPENAI_API_KEY"]
|
|
107
|
+
LLM.openai(key: ENV["OPENAI_API_KEY"])
|
|
108
|
+
elsif ENV["GOOGLE_API_KEY"]
|
|
109
|
+
LLM.google(key: ENV["GOOGLE_API_KEY"])
|
|
110
|
+
else
|
|
111
|
+
raise <<~MSG
|
|
112
|
+
No API key found. Set one of:
|
|
113
|
+
ANTHROPIC_API_KEY
|
|
114
|
+
OPENAI_API_KEY
|
|
115
|
+
GOOGLE_API_KEY
|
|
116
|
+
MSG
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
private_class_method :resolve_provider
|
|
121
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: brute
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Brute Contributors
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: llm.rb
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '4.11'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '4.11'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: async
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '2.0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '2.0'
|
|
40
|
+
description: Production-grade coding agent with tool execution, middleware pipeline,
|
|
41
|
+
context compaction, session persistence, and multi-provider LLM support.
|
|
42
|
+
executables: []
|
|
43
|
+
extensions: []
|
|
44
|
+
extra_rdoc_files: []
|
|
45
|
+
files:
|
|
46
|
+
- lib/brute.rb
|
|
47
|
+
- lib/brute/agent_stream.rb
|
|
48
|
+
- lib/brute/compactor.rb
|
|
49
|
+
- lib/brute/doom_loop.rb
|
|
50
|
+
- lib/brute/file_mutation_queue.rb
|
|
51
|
+
- lib/brute/hooks.rb
|
|
52
|
+
- lib/brute/middleware/base.rb
|
|
53
|
+
- lib/brute/middleware/compaction_check.rb
|
|
54
|
+
- lib/brute/middleware/doom_loop_detection.rb
|
|
55
|
+
- lib/brute/middleware/llm_call.rb
|
|
56
|
+
- lib/brute/middleware/reasoning_normalizer.rb
|
|
57
|
+
- lib/brute/middleware/retry.rb
|
|
58
|
+
- lib/brute/middleware/session_persistence.rb
|
|
59
|
+
- lib/brute/middleware/token_tracking.rb
|
|
60
|
+
- lib/brute/middleware/tool_error_tracking.rb
|
|
61
|
+
- lib/brute/middleware/tracing.rb
|
|
62
|
+
- lib/brute/orchestrator.rb
|
|
63
|
+
- lib/brute/patches/anthropic_tool_role.rb
|
|
64
|
+
- lib/brute/patches/buffer_nil_guard.rb
|
|
65
|
+
- lib/brute/pipeline.rb
|
|
66
|
+
- lib/brute/session.rb
|
|
67
|
+
- lib/brute/snapshot_store.rb
|
|
68
|
+
- lib/brute/system_prompt.rb
|
|
69
|
+
- lib/brute/todo_store.rb
|
|
70
|
+
- lib/brute/tools/delegate.rb
|
|
71
|
+
- lib/brute/tools/fs_patch.rb
|
|
72
|
+
- lib/brute/tools/fs_read.rb
|
|
73
|
+
- lib/brute/tools/fs_remove.rb
|
|
74
|
+
- lib/brute/tools/fs_search.rb
|
|
75
|
+
- lib/brute/tools/fs_undo.rb
|
|
76
|
+
- lib/brute/tools/fs_write.rb
|
|
77
|
+
- lib/brute/tools/net_fetch.rb
|
|
78
|
+
- lib/brute/tools/shell.rb
|
|
79
|
+
- lib/brute/tools/todo_read.rb
|
|
80
|
+
- lib/brute/tools/todo_write.rb
|
|
81
|
+
licenses:
|
|
82
|
+
- MIT
|
|
83
|
+
metadata: {}
|
|
84
|
+
rdoc_options: []
|
|
85
|
+
require_paths:
|
|
86
|
+
- lib
|
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
88
|
+
requirements:
|
|
89
|
+
- - ">="
|
|
90
|
+
- !ruby/object:Gem::Version
|
|
91
|
+
version: '3.2'
|
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
requirements: []
|
|
98
|
+
rubygems_version: 3.7.2
|
|
99
|
+
specification_version: 4
|
|
100
|
+
summary: A coding agent built on llm.rb
|
|
101
|
+
test_files: []
|