Module: Pikuri
- Defined in:
- lib/pikuri.rb,
lib/pikuri/tool.rb,
lib/pikuri/agent.rb,
lib/pikuri/version.rb,
lib/pikuri/tool/bash.rb,
lib/pikuri/tool/edit.rb,
lib/pikuri/tool/glob.rb,
lib/pikuri/tool/grep.rb,
lib/pikuri/tool/read.rb,
lib/pikuri/url_cache.rb,
lib/pikuri/subprocess.rb,
lib/pikuri/tool/fetch.rb,
lib/pikuri/tool/skill.rb,
lib/pikuri/tool/write.rb,
lib/pikuri/agent/tokens.rb,
lib/pikuri/agent/message.rb,
lib/pikuri/tool/confirmer.rb,
lib/pikuri/tool/sub_agent.rb,
lib/pikuri/tool/workspace.rb,
lib/pikuri/tool/calculator.rb,
lib/pikuri/tool/parameters.rb,
lib/pikuri/tool/search/exa.rb,
lib/pikuri/tool/web_scrape.rb,
lib/pikuri/tool/web_search.rb,
lib/pikuri/tool/scraper/pdf.rb,
lib/pikuri/agent/synthesizer.rb,
lib/pikuri/tool/scraper/html.rb,
lib/pikuri/tool/search/brave.rb,
lib/pikuri/tool/search/result.rb,
lib/pikuri/tool/skill_catalog.rb,
lib/pikuri/agent/listener_list.rb,
lib/pikuri/tool/scraper/simple.rb,
lib/pikuri/tool/search/engines.rb,
lib/pikuri/agent/chat_transport.rb,
lib/pikuri/tool/search/duckduckgo.rb,
lib/pikuri/agent/listener/terminal.rb,
lib/pikuri/agent/listener/token_log.rb,
lib/pikuri/tool/scraper/fetch_error.rb,
lib/pikuri/tool/search/rate_limiter.rb,
lib/pikuri/agent/listener/step_limit.rb,
lib/pikuri/agent/context_window_detector.rb,
lib/pikuri/agent/listener/message_listener.rb,
lib/pikuri/agent/listener/in_memory_message_list.rb
Overview
Boot file: configures the Zeitwerk autoloader for every file under lib/pikuri/ and eager-loads them all. After require ‘pikuri’, every constant pikuri ships (Pikuri::Agent, Pikuri::Tool, Pikuri::Tool::Calculator, Pikuri::Tool::Scraper::HTML, …) is defined and resolvable.
Beyond loading, the Pikuri module owns the logging surface — see Pikuri.logger_for, Pikuri.log_io=, and the PIKURI_LOG / PIKURI_LOG_<NAME> env vars. Each subsystem holds its own memoized Logger, all writing through a shared IO that Pikuri.log_io= can swap in one shot (handy in tests, daemons, or anywhere stderr isn’t the right sink).
Why eager-load
Tool implementations (Pikuri::Tool::CALCULATOR, Pikuri::Tool::WEB_SEARCH, Pikuri::Tool::WEB_SCRAPE, Pikuri::Tool::FETCH) are ALL_CAPS value constants rather than classes/modules, and Zeitwerk only auto-loads constants that match its filename-↔-CamelCase convention. Eager-loading at boot guarantees the files defining those values run, so the bin script can splat them straight into Pikuri::Agent.new(tools: […]) without per-file require ceremony. The cost is a few milliseconds of startup —negligible compared to a single LLM round-trip.
Defined Under Namespace
Classes: Agent, Subprocess, Tool, UrlCache
Constant Summary collapse
- PROMPTS_DIR =
Absolute path to the directory holding pikuri’s bundled system prompts (
pikuri-chat.txt,coding-system-prompt.txt). Resolves correctly both in a source checkout and in an installed gem because__dir__tracks the file’s actual location either way; the gem shipsprompts/as a sibling oflib/so the same relative jump works.Exposed publicly so a downstream library user can read pikuri’s prompts as a starting point for their own system prompt (or use them verbatim). Prefer prompt for the common case of loading one by name; reach for this constant only if you need the directory itself (e.g. to list available prompts).
File.('../prompts', __dir__)
- LOG_LEVELS =
Mapping from
PIKURI_LOGenv-var values (lowercased) to Logger level constants. Anything else falls back toINFO. { 'debug' => Logger::DEBUG, 'info' => Logger::INFO, 'warn' => Logger::WARN, 'error' => Logger::ERROR, 'fatal' => Logger::FATAL }.freeze
- Loader =
Zeitwerk::Loader.new
- VERSION =
Gem version, advertised in
pikuri.gemspec. Bump on every release following semver: patch for bug fixes, minor for backward-compatible additions to the public surface (Pikuri::Tool/Pikuri::Agent/ listeners / bundled tools), major for breaking changes to that surface or to thebin/pikuri-*CLIs. '0.0.1'
Class Attribute Summary collapse
-
.log_io ⇒ IO
Shared sink every Pikuri.logger_for writes through.
Class Method Summary collapse
-
.logger_for(name) ⇒ Logger
Memoized Logger tagged with
namein itsprogname, so each subsystem’s lines stand out in the shared sink. -
.prompt(name) ⇒ String
Read a bundled prompt by basename.
Class Attribute Details
.log_io ⇒ IO
Returns shared sink every logger_for writes through.
73 74 75 |
# File 'lib/pikuri.rb', line 73 def log_io @log_io end |
Class Method Details
.logger_for(name) ⇒ Logger
Memoized Logger tagged with name in its progname, so each subsystem’s lines stand out in the shared sink. Level resolves in this order: PIKURI_LOG_<NAME> (e.g. PIKURI_LOG_ENGINES=debug), then PIKURI_LOG, then INFO.
Repeated calls with the same name return the same instance so there is one logger per subsystem and log_io= can rewire them all in one shot.
110 111 112 113 114 115 116 117 |
# File 'lib/pikuri.rb', line 110 def logger_for(name) @log_loggers[name] ||= begin lg = Logger.new(@log_io, progname: name) override = ENV["PIKURI_LOG_#{name.upcase}"].to_s.downcase lg.level = LOG_LEVELS.fetch(override, @log_default) lg end end |
.prompt(name) ⇒ String
Read a bundled prompt by basename. name is matched against the files in PROMPTS_DIR; a .txt extension is auto-appended if absent. Symbols are accepted as a convenience (:pikuri-chat / ‘pikuri-chat’ / ‘pikuri-chat.txt’ all resolve to the same file).
Intended for downstream library users who want to bootstrap their own Pikuri::Agent wiring from pikuri’s defaults — read the prompt, customize the bits they care about, hand the result to Agent.new(system_prompt: …).
136 137 138 139 140 141 142 143 144 145 |
# File 'lib/pikuri.rb', line 136 def prompt(name) basename = name.to_s basename += '.txt' unless basename.end_with?('.txt') path = File.join(PROMPTS_DIR, basename) unless File.exist?(path) available = Dir.children(PROMPTS_DIR).sort.join(', ') raise ArgumentError, "Unknown pikuri prompt #{name.inspect}; available: #{available}" end File.read(path) end |