hellm 0.0.2 → 0.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c138b33e657f7ed52bdc37c4b9883574eeef25b6e479d4760922f6e4300a5c30
4
- data.tar.gz: be896fe016921e7e0ce7924512ca5277b96d83bdd49b90182996002d0fc73ca6
3
+ metadata.gz: 11522217c18c262d67881d31f50efb136d43fb3f9465c3ed25cbf95659b927ef
4
+ data.tar.gz: bf00259cd39073946654e42e8c63a04fe95310fbd94b12d772929c7fc8194b5c
5
5
  SHA512:
6
- metadata.gz: d516481c8315a8133db672a29c166b45962433693553d15ce725fbf6a0c3070933184cf2b861b82be33ea0b8b5a51ec18e110962d88dccea83583a0c13f49550
7
- data.tar.gz: 205aecc4a739328e1860b00a5681a4de55eb5c72172cd174e088d864b86f5c2d920e0b6936f706445e4d5108402cd2301748ccf9618b74b9ea29475a5145315c
6
+ metadata.gz: cf31d07cca0558b43e1fbbcaf338493e268352867e450b1f98cda732f8728fe5685dbb6a10e23ccb749e7b323d59e3673e0bdaace0a2629c623c83013bb2355d
7
+ data.tar.gz: 48919c27642fba873c2d4348b933fc899bb3735e42e57590639c058cb835462727c3ac91861754ba279aebf4c82eae7d9e737884c4fbae486130e89534d8fea1
data/ARCHITECTURE.md CHANGED
@@ -140,6 +140,24 @@ Responsibilities:
140
140
  - Builds dynamic Langchain tools that proxy calls into sub-agents
141
141
  - Starts a fresh sub-agent session per invocation
142
142
 
143
+ ### Hellm::Tools::WebFetchTool
144
+
145
+ Location: lib/hellm/tools/web_fetch_tool.rb
146
+
147
+ Responsibilities:
148
+ - Reads raw content from HTTP(S) URLs
149
+ - Extracts plain text from HTML pages using Nokogiri
150
+ - Returns resilient error strings for network/parsing failures
151
+
152
+ ### Hellm::Tools::BraveSearchTool
153
+
154
+ Location: lib/hellm/tools/brave_search_tool.rb
155
+
156
+ Responsibilities:
157
+ - Calls Brave::SearchApi for web search requests
158
+ - Exposes query/count/offset/country parameters as a tool function
159
+ - Serializes search responses to JSON for agent consumption
160
+
143
161
  ## Configuration Model
144
162
 
145
163
  Project configuration is stored in a `.hellm` directory with the following structure:
@@ -172,8 +190,8 @@ Current technical risks:
172
190
  - Minimal validation of markdown frontmatter means malformed config errors may surface late.
173
191
 
174
192
  Testing status:
175
- - RSpec covers core behavior for Builder, Registry, tools, and LLM-free Agent logic.
176
- - SimpleCov runs with the suite and writes coverage output to log/coverage.
193
+ - RSpec covers core behavior for Builder, Registry, tool classes (including WebFetchTool and BraveSearchTool), and LLM-free Agent logic.
194
+ - SimpleCov runs with the suite and writes coverage output to log/reports/coverage.
177
195
 
178
196
  ## Future Hardening Priorities
179
197
 
data/README.md CHANGED
@@ -47,7 +47,12 @@ hellm Alfred "Tell me your favorite color and which month fits it."
47
47
 
48
48
  The framework provides the following tools for agents to use:
49
49
 
50
- * `calculator` - a simple calculator for basic arithmetic operations.
50
+ | Tool Name | Aliases | Description |
51
+ | ------------- | ----------------------- | ------------------------------------------------------- |
52
+ | `calculator` | | a simple calculator for basic arithmetic operations. |
53
+ | `webfetch` | `web` | fetches web pages or other content from URLs. |
54
+ | `websearch` | `web` | performs web searches and returns search results. |
55
+ | `web` | | combines web fetching and web searching capabilities. |
51
56
 
52
57
 
53
58
  ### Custom Tools
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.4
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: Alfred
3
3
  description: "General purpose agent."
4
- tools: [agent]
4
+ tools: [agent, web]
5
5
  agents: [Mathematician]
6
6
  ---
7
7
 
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/bash
2
+
3
+ ../bin/hellm Alfred what products is ubity advertising on its homepage at https://ubity.io
@@ -0,0 +1,34 @@
1
+ module Brave
2
+ module SearchApi
3
+ class Client
4
+ BASE_URL = "https://api.search.brave.com/res/v1/web/search"
5
+
6
+ def initialize(api_key)
7
+ @api_key = api_key
8
+ end
9
+
10
+ def search(query, country: nil, count: 10, offset: 0)
11
+ uri = URI(BASE_URL)
12
+ params = {
13
+ q: query,
14
+ count: count,
15
+ offset: offset,
16
+ country: country
17
+ }
18
+
19
+ headers = {
20
+ "X-Subscription-Token" => @api_key,
21
+ "Content-Type" => "application/json"
22
+ }
23
+
24
+ response = Net::HTTP.post(uri, params.to_json, headers)
25
+
26
+ if response.is_a?(Net::HTTPSuccess)
27
+ JSON.parse(response.body)
28
+ else
29
+ raise "Brave Search API request failed with status #{response.code}: #{response.message}"
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,10 @@
1
+ require_relative "search_api/client"
2
+
3
+ module Brave
4
+ module SearchApi
5
+ def self.search(query, country: nil, count: 10, offset: 0)
6
+ client = Client.new(Brave.api_key)
7
+ client.search(query, country: country, count: count, offset: offset)
8
+ end
9
+ end
10
+ end
data/lib/brave.rb ADDED
@@ -0,0 +1,7 @@
1
+ require_relative "brave/search_api"
2
+
3
+ module Brave
4
+ def self.api_key
5
+ ENV["BRAVE_API_KEY"]
6
+ end
7
+ end
data/lib/hellm/agent.rb CHANGED
@@ -41,8 +41,6 @@ class Hellm::Agent
41
41
  self.stream_adapter = stream_adapter || Hellm::StreamAdapter.new
42
42
  self.agents = agents || []
43
43
  self.tools = tools || []
44
- # remove "agent" from tools, this ability is controlled by the presence of agents
45
- self.tools.reject!{|t| t == "agent"}
46
44
  end
47
45
 
48
46
 
data/lib/hellm/builder.rb CHANGED
@@ -1,8 +1,10 @@
1
+ require_relative "markdown_file"
2
+ require_relative "stream_adapter"
1
3
  require_relative "agent"
2
4
  require_relative "skill"
3
- require_relative "stream_adapter"
4
5
  require_relative "tools/skill_tool"
5
- require_relative "markdown_file"
6
+ require_relative "tools/web_fetch_tool"
7
+ require_relative "tools/brave_search_tool"
6
8
 
7
9
  class Hellm::Builder
8
10
  attr_accessor :project_dir, :hellm_dir, :stream_adapter
@@ -42,6 +44,8 @@ class Hellm::Builder
42
44
  private
43
45
  def add_builtin_tools_to_registry
44
46
  Hellm::Tools::Registry.instance.add(:calculator) { Langchain::Tool::Calculator.new }
47
+ Hellm::Tools::Registry.instance.add(:bravesearch) { Hellm::Tools::BraveSearchTool.new }
48
+ Hellm::Tools::Registry.instance.add(:webfetch) { Hellm::Tools::WebFetchTool.new }
45
49
  end
46
50
 
47
51
  def get_skills_from_project_dir
@@ -69,7 +73,7 @@ class Hellm::Builder
69
73
  markdown_file = Hellm::MarkdownFile.read(file)
70
74
 
71
75
  tools = markdown_file.fetch("tools", [])
72
- tools << "skill"
76
+ tools << "default"
73
77
 
74
78
  Hellm::Agent.new(
75
79
  model: markdown_file.fetch("model"),
@@ -0,0 +1,20 @@
1
+ require "brave"
2
+
3
+ module Hellm::Tools
4
+ class BraveSearchTool
5
+ extend Langchain::ToolDefinition
6
+
7
+ define_function :search, description: "Performs a web search using 'Brave Search' search engine." do
8
+ property :query, type: "string", description: "The search query.", required: true
9
+ property :count, type: "integer", description: "The number of search results to return.", required: false
10
+ property :offset, type: "integer", description: "The offset for the search results.", required: false
11
+ property :country, type: "string", description: "The 2-letter country code for the search results.", required: false
12
+ end
13
+
14
+ def search(query:, count: 10, offset: 0, country: nil)
15
+ results = Brave::SearchApi.search(query, count: count, offset: offset, country: country)
16
+ results.to_json
17
+ end
18
+
19
+ end
20
+ end
@@ -2,6 +2,14 @@ require_relative "agent_tool_factory"
2
2
 
3
3
  module Hellm::Tools
4
4
  class Registry
5
+ ALIASES = {
6
+ "default" => ["skill"],
7
+ "web" => ["webfetch", "bravesearch"],
8
+ "websearch" => ["bravesearch"],
9
+ "agent" => [] # agent tools are dynamically generated from registered agents
10
+ }
11
+
12
+
5
13
  def self.instance
6
14
  @instance ||= new
7
15
  end
@@ -19,6 +27,7 @@ module Hellm::Tools
19
27
  end
20
28
 
21
29
  def get(*tool_names)
30
+ tool_names = resolve_aliases(*tool_names)
22
31
  tools = tool_names.map do |tool_name|
23
32
  entry = @tools[tool_name.to_s]
24
33
  if entry.nil?
@@ -49,5 +58,11 @@ module Hellm::Tools
49
58
  def agent_tool_name(agent_name)
50
59
  "agent_tool_" + agent_name.gsub(/[\s-]+/, "_").downcase
51
60
  end
61
+
62
+ def resolve_aliases(*tool_names)
63
+ tool_names.map do |tool_name|
64
+ ALIASES.fetch(tool_name.to_s, [tool_name.to_s])
65
+ end.flatten
66
+ end
52
67
  end
53
68
  end
@@ -0,0 +1,32 @@
1
+ require "open-uri"
2
+ require "nokogiri"
3
+
4
+ module Hellm::Tools
5
+ class WebFetchTool
6
+ extend Langchain::ToolDefinition
7
+
8
+ define_function :read, description: "Reads content from a URL. Use this function when you want to get text/binary raw data from the response, e.g. to check the HTML-code of a page." do
9
+ property :url, type: "string", description: "The URL to read from."
10
+ end
11
+
12
+ define_function :read_text, description: "Reads HTML text content from a URL. Use this function to extract text only from a HTML page." do
13
+ property :url, type: "string", description: "The URL to read from."
14
+ end
15
+
16
+ def read(url:)
17
+ URI.open(url).read
18
+ rescue StandardError => e
19
+ "Failed to read from URL #{url}: #{e.message}"
20
+ end
21
+
22
+ def read_text(url:)
23
+ html_content = URI.open(url).read
24
+ text = Nokogiri::HTML(html_content).text
25
+ lines = text.lines.map(&:strip).reject(&:empty?)
26
+ lines.join("\n")
27
+ rescue StandardError => e
28
+ "Failed to extract text from URL #{url}: #{e.message}"
29
+ end
30
+
31
+ end
32
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hellm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - ubity UG
@@ -67,19 +67,33 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: 1.6.5
69
69
  - !ruby/object:Gem::Dependency
70
- name: google_search_results
70
+ name: nokogiri
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 2.2.0
75
+ version: 1.19.4
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 2.2.0
82
+ version: 1.19.4
83
+ - !ruby/object:Gem::Dependency
84
+ name: gsearch-parser
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.2.2
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.2.2
83
97
  description: |
84
98
  Declarative agentic framework for LLMs, allowing you to build autonomous agents that can perform complex tasks and interact with the world, without writing code.
85
99
  Agents and skills are defined in markdown files, quite similar to how Github Copilot works.
@@ -102,7 +116,11 @@ files:
102
116
  - example/.hellm/agents/alfred.agent.md
103
117
  - example/.hellm/agents/mathematician.agent.md
104
118
  - example/.hellm/skills/farben/SKILL.md
105
- - example/example.sh
119
+ - example/example1.sh
120
+ - example/example2.sh
121
+ - lib/brave.rb
122
+ - lib/brave/search_api.rb
123
+ - lib/brave/search_api/client.rb
106
124
  - lib/hellm.rb
107
125
  - lib/hellm/agent.rb
108
126
  - lib/hellm/builder.rb
@@ -110,8 +128,10 @@ files:
110
128
  - lib/hellm/skill.rb
111
129
  - lib/hellm/stream_adapter.rb
112
130
  - lib/hellm/tools/agent_tool_factory.rb
131
+ - lib/hellm/tools/brave_search_tool.rb
113
132
  - lib/hellm/tools/registry.rb
114
133
  - lib/hellm/tools/skill_tool.rb
134
+ - lib/hellm/tools/web_fetch_tool.rb
115
135
  - lib/hellm/version.rb
116
136
  - sig/hellm.rbs
117
137
  homepage: https://gitlab.com/ubity/gems/hellm
File without changes