Module: RubyPi::Context::Transform
- Defined in:
- lib/ruby_pi/context/transform.rb
Overview
Factory methods for building transform_context callables. Each method returns a Proc that accepts an Agent::State and mutates it. Use ‘compose` to chain multiple transforms.
Constant Summary collapse
- DATETIME_START_MARKER =
Marker delimiters for idempotent injection. Each injection type has unique start/end markers so they can be independently stripped and re-added without affecting each other.
"<!-- RUBYPI_DATETIME_START -->"- DATETIME_END_MARKER =
"<!-- RUBYPI_DATETIME_END -->"- PREFS_START_MARKER =
"<!-- RUBYPI_PREFS_START -->"- PREFS_END_MARKER =
"<!-- RUBYPI_PREFS_END -->"- WORKSPACE_START_MARKER =
"<!-- RUBYPI_WORKSPACE_START -->"- WORKSPACE_END_MARKER =
"<!-- RUBYPI_WORKSPACE_END -->"
Class Method Summary collapse
-
.compose(*transforms) ⇒ Proc
Chains multiple transform callables into a single callable that executes them in order.
-
.inject_datetime ⇒ Proc
Returns a transform that appends the current date and time to the system prompt.
-
.inject_user_preferences {|state| ... } ⇒ Proc
Returns a transform that appends user preferences to the system prompt.
-
.inject_workspace_context {|state| ... } ⇒ Proc
Returns a transform that appends workspace context to the system prompt.
Class Method Details
.compose(*transforms) ⇒ Proc
Chains multiple transform callables into a single callable that executes them in order. Each transform receives the same State object and can mutate it freely.
54 55 56 57 58 |
# File 'lib/ruby_pi/context/transform.rb', line 54 def compose(*transforms) ->(state) do transforms.each { |t| t.call(state) } end end |
.inject_datetime ⇒ Proc
Returns a transform that appends the current date and time to the system prompt. Useful for giving the LLM temporal awareness.
This injection is IDEMPOTENT: it strips any existing datetime injection (identified by markers) before re-adding, so calling it N times in a loop produces exactly one datetime block.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/ruby_pi/context/transform.rb', line 72 def inject_datetime ->(state) do = Time.now.utc.strftime("%Y-%m-%d %H:%M:%S UTC") # Strip any existing datetime injection before re-adding. # This makes the transform idempotent — calling it multiple times # across loop iterations does not accumulate duplicate timestamps. state.system_prompt = strip_between_markers( state.system_prompt, DATETIME_START_MARKER, DATETIME_END_MARKER ) state.system_prompt += "\n\n#{DATETIME_START_MARKER}\nCurrent date and time: #{}\n#{DATETIME_END_MARKER}" end end |
.inject_user_preferences {|state| ... } ⇒ Proc
Returns a transform that appends user preferences to the system prompt. The block is called with the state and should return a string or hash of preferences. If nil is returned, nothing is appended.
This injection is IDEMPOTENT: existing preferences are stripped before re-adding.
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/ruby_pi/context/transform.rb', line 104 def inject_user_preferences(&block) ->(state) do preferences = block.call(state) # Always strip existing preferences injection first for idempotency state.system_prompt = strip_between_markers( state.system_prompt, PREFS_START_MARKER, PREFS_END_MARKER ) return if preferences.nil? prefs_text = preferences.is_a?(Hash) ? format_hash(preferences) : preferences.to_s state.system_prompt += "\n\n#{PREFS_START_MARKER}\n[User Preferences]\n#{prefs_text}\n#{PREFS_END_MARKER}" end end |
.inject_workspace_context {|state| ... } ⇒ Proc
Returns a transform that appends workspace context to the system prompt. The block is called with the state and should return contextual information about the current workspace/project.
This injection is IDEMPOTENT: existing workspace context is stripped before re-adding.
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/ruby_pi/context/transform.rb', line 134 def inject_workspace_context(&block) ->(state) do context = block.call(state) # Always strip existing workspace injection first for idempotency state.system_prompt = strip_between_markers( state.system_prompt, WORKSPACE_START_MARKER, WORKSPACE_END_MARKER ) return if context.nil? ctx_text = context.is_a?(Hash) ? format_hash(context) : context.to_s state.system_prompt += "\n\n#{WORKSPACE_START_MARKER}\n[Workspace Context]\n#{ctx_text}\n#{WORKSPACE_END_MARKER}" end end |