Class: Rubino::Context::EnvironmentInspector
- Inherits:
-
Object
- Object
- Rubino::Context::EnvironmentInspector
- Defined in:
- lib/rubino/context/environment_inspector.rb
Overview
Builds the “[Environment]” block injected into every system prompt.
Probes the host once per process for the static bits (OS, ruby/python versions, external utilities on PATH) and asks for the dynamic bits (date, cwd, git branch) on every build. The static cache survives the length of the process — long enough for an HTTP server’s lifetime, short enough that a ‘gem install` between deploys repopulates it.
The goal is a concrete, honest description of the actual runtime the model is talking to. If markitdown isn’t installed in the VM image, we don’t list it — the agent will then ask the user instead of confidently invoking a binary that doesn’t exist.
Constant Summary collapse
- DEFAULT_UTILITIES =
External CLI tools we probe by default. The list mixes hard dependencies (git, ruby) and useful-but-optional binaries the agent may want to shell out to (markitdown, pandoc, …). Anything not found on PATH is silently dropped — see #available_utilities.
%w[ git gh rg jq curl wget ruby python3 node npm bundle docker psql sqlite3 redis-cli ffmpeg pandoc markitdown pdftotext tesseract ].freeze
Class Method Summary collapse
-
.cache ⇒ Object
Process-wide cache of the static fields.
- .reset_cache! ⇒ Object
Instance Method Summary collapse
-
#available_utilities ⇒ Object
Public for spec inspection.
-
#document_formats ⇒ Object
The CORE document formats readable in-process via read_attachment (driven by which optional extraction gems loaded).
-
#initialize(extra_utilities: [], cwd: nil, clock: -> { Time.now }) ⇒ EnvironmentInspector
constructor
A new instance of EnvironmentInspector.
-
#render ⇒ Object
Returns the assembled [Environment] block, or nil if the caller disabled it at the config layer (PromptAssembler decides — this class always renders when asked).
Constructor Details
#initialize(extra_utilities: [], cwd: nil, clock: -> { Time.now }) ⇒ EnvironmentInspector
Returns a new instance of EnvironmentInspector.
44 45 46 47 48 |
# File 'lib/rubino/context/environment_inspector.rb', line 44 def initialize(extra_utilities: [], cwd: nil, clock: -> { Time.now }) @extra_utilities = Array(extra_utilities).map(&:to_s) @cwd = cwd @clock = clock end |
Class Method Details
.cache ⇒ Object
Process-wide cache of the static fields. Reset via #reset_cache! from specs.
35 36 37 |
# File 'lib/rubino/context/environment_inspector.rb', line 35 def cache @cache ||= {} end |
.reset_cache! ⇒ Object
39 40 41 |
# File 'lib/rubino/context/environment_inspector.rb', line 39 def reset_cache! @cache = {} end |
Instance Method Details
#available_utilities ⇒ Object
Public for spec inspection. The list is sorted to keep the prompt stable turn-to-turn (otherwise reordering would invalidate the provider-side prompt cache).
88 89 90 91 |
# File 'lib/rubino/context/environment_inspector.rb', line 88 def available_utilities probes = (DEFAULT_UTILITIES + @extra_utilities).uniq self.class.cache[:utilities] ||= probes.select { |bin| on_path?(bin) }.sort end |
#document_formats ⇒ Object
The CORE document formats readable in-process via read_attachment (driven by which optional extraction gems loaded). Advertised so the model knows it can read a docx/pdf even when no ‘markitdown` binary exists on PATH – closing the gap this file’s own comment describes.
77 78 79 80 81 82 83 |
# File 'lib/rubino/context/environment_inspector.rb', line 77 def document_formats self.class.cache[:document_formats] ||= begin Rubino::Documents::Registry.available_formats rescue StandardError [] end end |
#render ⇒ Object
Returns the assembled [Environment] block, or nil if the caller disabled it at the config layer (PromptAssembler decides — this class always renders when asked).
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/rubino/context/environment_inspector.rb', line 53 def render lines = [] lines << "[Environment]" lines << "- Today's date: #{today}" lines << "- Platform: #{platform}" lines << "- Shell: #{shell}" lines << "- Working dir: #{working_dir}" git = git_description lines << "- Git: #{git}" if git lines << "- Runtimes: #{runtimes}" utilities = available_utilities lines << "- Available CLI tools on PATH: #{utilities.join(", ")}" if utilities.any? docs = document_formats if docs.any? lines << "- Document reading: the `read_attachment` tool converts these formats " \ "to Markdown in-process (no external binary needed): #{docs.join(", ")}" end lines.join("\n") end |