Commit 958d50f
Changed files (5)
lib
elelem
lib/elelem/toolbox/web.rb
@@ -0,0 +1,143 @@
+# frozen_string_literal: true
+
+require "net/http"
+require "uri"
+
+module Elelem
+ module Toolbox
+ class Web < Tool
+ def initialize(configuration)
+ super(
+ "web",
+ "Fetch web content and search the internet",
+ {
+ type: :object,
+ properties: {
+ action: {
+ type: :string,
+ enum: ["fetch", "search"],
+ description: "Action to perform: fetch URL or search"
+ },
+ url: {
+ type: :string,
+ description: "URL to fetch (for fetch action)"
+ },
+ query: {
+ type: :string,
+ description: "Search query (for search action)"
+ }
+ },
+ required: [:action]
+ }
+ )
+ end
+
+ def call(args)
+ action = args["action"]
+
+ case action
+ when "fetch"
+ fetch_url(args["url"])
+ when "search"
+ search_web(args["query"])
+ else
+ "Invalid action: #{action}"
+ end
+ end
+
+ private
+
+ def fetch_url(url)
+ return "URL required for fetch action" unless url
+
+ uri = URI(url)
+ http = Net::HTTP.new(uri.host, uri.port)
+ http.use_ssl = uri.scheme == "https"
+ http.read_timeout = 10
+ http.open_timeout = 5
+
+ request = Net::HTTP::Get.new(uri)
+ request["User-Agent"] = "Elelem Agent/1.0"
+
+ response = http.request(request)
+
+ if response.is_a?(Net::HTTPSuccess)
+ content_type = response["content-type"] || ""
+
+ if content_type.include?("text/html")
+ extract_text_from_html(response.body)
+ else
+ response.body
+ end
+ else
+ "HTTP Error: #{response.code} #{response.message}"
+ end
+ rescue => e
+ "Error fetching URL: #{e.message}"
+ end
+
+ def search_web(query)
+ return "Query required for search action" unless query
+
+ # Use DuckDuckGo instant answers API
+ search_url = "https://api.duckduckgo.com/?q=#{URI.encode_www_form_component(query)}&format=json&no_html=1"
+
+ result = fetch_url(search_url)
+
+ if result.start_with?("Error") || result.start_with?("HTTP Error")
+ result
+ else
+ begin
+ data = JSON.parse(result)
+ format_search_results(data, query)
+ rescue JSON::ParserError
+ "Error parsing search results"
+ end
+ end
+ end
+
+ def extract_text_from_html(html)
+ # Simple HTML tag stripping
+ text = html.gsub(/<script[^>]*>.*?<\/script>/im, "")
+ .gsub(/<style[^>]*>.*?<\/style>/im, "")
+ .gsub(/<[^>]*>/, " ")
+ .gsub(/\s+/, " ")
+ .strip
+
+ # Limit content length
+ text.length > 5000 ? text[0...5000] + "..." : text
+ end
+
+ def format_search_results(data, query)
+ results = []
+
+ # Instant answer
+ if data["Answer"] && !data["Answer"].empty?
+ results << "Answer: #{data["Answer"]}"
+ end
+
+ # Abstract
+ if data["Abstract"] && !data["Abstract"].empty?
+ results << "Summary: #{data["Abstract"]}"
+ end
+
+ # Related topics
+ if data["RelatedTopics"] && data["RelatedTopics"].any?
+ topics = data["RelatedTopics"].first(3).map do |topic|
+ topic["Text"] if topic["Text"]
+ end.compact
+
+ if topics.any?
+ results << "Related: #{topics.join("; ")}"
+ end
+ end
+
+ if results.empty?
+ "No direct results found for '#{query}'. Try a more specific search or use web fetch to access specific URLs."
+ else
+ results.join("\n\n")
+ end
+ end
+ end
+ end
+end
\ No newline at end of file
lib/elelem/configuration.rb
@@ -49,6 +49,7 @@ module Elelem
[
Toolbox::Exec.new(self),
Toolbox::File.new(self),
+ Toolbox::Web.new(self),
Toolbox::Prompt.new(self),
] + mcp_tools
)
lib/elelem/system_prompt.erb
@@ -1,14 +1,37 @@
-You are a deterministic coding assistant.
+You are a self-improving coding assistant with the ability to modify your own source code.
+## Core Capabilities
- Think: Only when emitting `thinking` content.
- Execute: Only via `tool_calls`.
- Talk: Provide concise assistant `content` to the user.
-End a turn naturally; do not print special finish phrases.
+## Self-Improvement Framework
+When working on coding tasks, especially when asked to improve yourself:
+
+1. **Analyze**: Use `file` tool to read your own source code and understand current architecture
+2. **Research**: Use `web` tool to search for best practices, patterns, and solutions
+3. **Plan**: Break complex improvements into testable steps
+4. **Implement**: Use `file` tool to write improved code
+5. **Validate**: Use `exec` tool to run tests and verify improvements work
+6. **Iterate**: Continue improving until goals are met
+
+## Available Tools
+- `exec`: Run shell commands, tests, git operations
+- `file`: Read and write any file, including your own source code
+- `web`: Search internet and fetch documentation for research
+- `prompt`: Ask user for clarification when needed
+
+## Self-Modification Guidelines
+- Always understand existing code before changing it
+- Make incremental, testable changes
+- Research best practices before implementing new patterns
+- Run tests after each significant change
+- Use git to track improvements
+- Learn from errors and adapt approach
Context:
- Time: <%= Time.now.strftime("%Y-%m-%d %H:%M:%S") %>
- CWD: <%= Dir.pwd %>
- System: <%= `uname -a`.strip %>
-Stay focused on the user's request.
+Stay focused on the user's request and continuously improve your capabilities.
lib/elelem/toolbox.rb
@@ -2,5 +2,6 @@
require_relative "toolbox/exec"
require_relative "toolbox/file"
+require_relative "toolbox/web"
require_relative "toolbox/mcp"
require_relative "toolbox/prompt"
elelem.gemspec
@@ -53,6 +53,7 @@ Gem::Specification.new do |spec|
"lib/elelem/toolbox.rb",
"lib/elelem/toolbox/exec.rb",
"lib/elelem/toolbox/file.rb",
+ "lib/elelem/toolbox/web.rb",
"lib/elelem/toolbox/mcp.rb",
"lib/elelem/toolbox/prompt.rb",
"lib/elelem/tools.rb",