Class: Insika::Tools::SaveArtifact

Inherits:
RubyLLM::Tool
  • Object
show all
Defined in:
lib/insika/tools/save_artifact.rb

Overview

save_artifact — the agent delivers a page (a report, a digest) to a destination that survives the channel: title + content in, a URL out, which it can include in a channel message ("today's report: ").

A REGISTRY tool (not a ChatBuilder system tool): the per-agent tools_allow is the switch — registered optional: true, so an agent that did not name it cannot call it, and nothing global enables it. The bindings (tenant, agent, task) are the tool INSTANCE's, deposited by the Executor into turn_context like a data-tool's — never parameters the model types.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(artifact_store:, base_url: nil, signing_key: nil, signing_ttl: nil, max_bytes: nil, event_stream: nil) ⇒ SaveArtifact

Returns a new instance of SaveArtifact.



29
30
31
32
33
34
35
36
37
38
# File 'lib/insika/tools/save_artifact.rb', line 29

def initialize(artifact_store:, base_url: nil, signing_key: nil, signing_ttl: nil,
               max_bytes: nil, event_stream: nil)
  @artifact_store = artifact_store
  @base_url = base_url.to_s.sub(%r{/\z}, "")
  @signing_key = signing_key
  @signing_ttl = signing_ttl
  @max_bytes = max_bytes
  @event_stream = event_stream
  super()
end

Instance Attribute Details

#turn_contextObject

Per-turn bindings, deposited by the Executor (ToolAssembly's turn_context= seam — the same one data-tools use). From the TURN, never from the model (the tenant-lesson: an id the model types is inventable, and the turn looks right anyway).



44
45
46
# File 'lib/insika/tools/save_artifact.rb', line 44

def turn_context
  @turn_context
end

Instance Method Details

#execute(title:, content:, mime: "text/html") ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/insika/tools/save_artifact.rb', line 50

def execute(title:, content:, mime: "text/html")
  # the deployment's size cap rides the tool instance (INSIKA_ARTIFACT_
  # MAX_BYTES at wiring); absent -> the store's default.
  attrs = { tenant: binding_tenant, agent: @turn_context&.dig(:agent_id),
            task_id: @turn_context&.dig(:task_id), title: title, mime: mime,
            content: content }
  attrs[:max_bytes] = @max_bytes if @max_bytes
  record = @artifact_store.create(**attrs)
  # the authenticated Studio URL is the always-on answer; the signed
  # link exists ONLY when a key was configured (it shares OUTSIDE the
  # Studio and expires).
  url = Insika::ArtifactSigning.url_for(id: record.id, base: @base_url)
  result = { id: record.id, url: url }
  signed = Insika::ArtifactSigning.url_for(
    id: record.id, base: @base_url, key: @signing_key, ttl: @signing_ttl
  )
  result[:signed_url] = signed if signed != url
  emit(record)
  result
rescue Insika::ValidationError => e
  { error: e.message }
end

#nameObject



27
# File 'lib/insika/tools/save_artifact.rb', line 27

def name = "save_artifact"