Class: Protege::CreateFileTool

Inherits:
Tool
  • Object
show all
Defined in:
app/tools/protege/create_file_tool.rb

Overview

Built-in tool that turns content the agent authored into a stored file it can later attach to an email. Subclasses Protege::Tool, so the harness publishes it in the LLM's tool catalog (id :create_file); when the model calls it, the harness routes the arguments to #use.

The file is written to Active Storage as a standalone ActiveStorage::Blob (no owner record) and the tool returns its blob_id. That id is the currency the send_email tool accepts, so the flow is: author content here, get a blob id, then reference it from +send_email+'s attachments. Keeping storage and sending as two steps lets the agent create several files, review them via read_attachment, and attach any subset.

The LLM only ever supplies text; the engine never asks it for binary bytes. The format enum is therefore the whole capability surface — each maps to a content type the authored text is stored under. A format that needs a real transform (e.g. HTML->PDF) is a later addition; today every format stores the text as-is.

Constant Summary collapse

FORMATS =

Supported formats mapped to the content type the authored text is stored under. The keys are the format enum; the format name is also the file extension. New text formats are one row here.

{
  csv:  'text/csv',
  txt:  'text/plain',
  md:   'text/markdown',
  html: 'text/html',
  json: 'application/json',
  svg:  'image/svg+xml'
}.freeze

Instance Method Summary collapse

Instance Method Details

#use(context:, format:, filename:, content:) ⇒ Protege::Result

Render the authored content to a stored blob and return its id.

Parameters:

  • context (Protege::Orchestrator::Context)

    the per-run context (unused — a blob has no owner)

  • format (String)

    one of FORMATS's keys

  • filename (String)

    the base filename; normalized to carry the format's extension

  • content (String)

    the file content the model authored

Returns:

  • (Protege::Result)

    success carrying blob_id and metadata, or a failure (unknown format or a size-limit breach)



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'app/tools/protege/create_file_tool.rb', line 72

def use(context:, format:, filename:, content:)
  content_type = FORMATS[format.to_sym]
  return failure(reason: "unknown format #{format.inspect}") unless content_type

  bytes     = content.to_s.b
  violation = Protege.configuration.attachment_policy.violation(byte_sizes: [bytes.bytesize])
  return failure(reason: violation) if violation

  blob = ActiveStorage::Blob.create_and_upload!(
    io:           StringIO.new(bytes),
    filename:     with_extension(filename, format),
    content_type:
  )

  success(
    blob_id:      blob.id,
    filename:     blob.filename.to_s,
    byte_size:    blob.byte_size,
    content_type:
  )
end