Class: Protege::LoadFileResolver

Inherits:
Resolver
  • Object
show all
Defined in:
app/resolvers/protege/load_file_resolver.rb

Overview

General-purpose resolver that reads a file and contributes its contents as one context message. It is deliberately not named for a use case: the developer decides what the file is — a system prompt, a knowledge document, few-shot examples — by choosing the role of the emitted message.

The path is given either statically or as a block that receives the resolver context, so it can be derived from the inbound message or persona (e.g. a per-persona prompt file). Path resolution mirrors ordinary shell intuition, so the same resolver works in development and in any production deployment:

  • a relative path (+config/personas/agent.md+, ./agent.md) resolves against the host app root (+Rails.root+) — i.e. a file deployed with the app, which is reliably readable everywhere.
  • an absolute path (+/data/prompts/agent.md+) is used as-is, so an attached volume or mounted secret just needs its fully-qualified path.

LoadFileResolver is a developer-wired resolver, never a model-callable tool — the path is author-trusted code, so even absolute reads carry the same trust as any code in the persona. A missing file is a misconfiguration and raises Protege::ResolverFileNotFoundError; a blank file contributes nothing (returns nil).

resolvers do |chain|
chain.use Protege::LoadFileResolver, 'config/personas/agent.md'
chain.use(Protege::LoadFileResolver) { |ctx| "config/personas/#{ctx.persona.name.parameterize}.md" }
end

Instance Method Summary collapse

Constructor Details

#initialize(path = nil, role: :system) {|context| ... } ⇒ LoadFileResolver

Returns a new instance of LoadFileResolver.

Parameters:

  • path (String, nil) (defaults to: nil)

    file to read; relative paths resolve against Rails.root, absolute paths are used verbatim. Omit when supplying a block instead.

  • role (Symbol) (defaults to: :system)

    role for the emitted message (+:system+ for a prompt, +:user+/+:assistant+ to seed conversation); defaults to :system

Yield Parameters:

Yield Returns:

  • (String)

    the path to read, computed per delivery

Raises:

  • (ArgumentError)

    unless exactly one of path or a block is given



34
35
36
37
38
39
40
41
# File 'app/resolvers/protege/load_file_resolver.rb', line 34

def initialize(path = nil, role: :system, &block)
  super()
  raise ArgumentError, 'LoadFileResolver requires exactly one of a path or a block' unless path.nil? ^ block.nil?

  @path  = path
  @role  = role
  @block = block
end

Instance Method Details

#resolve(context:) ⇒ Protege::ModelMessage?

Read the file and emit its contents as a single message, or nil when the file is blank.

Parameters:

Returns:

Raises:



48
49
50
51
52
53
# File 'app/resolvers/protege/load_file_resolver.rb', line 48

def resolve(context:)
  content = read(path_for(context))
  return nil if content.blank?

  message(role: @role, content:)
end