Class: Insika::Tools::Tts
- Inherits:
-
RubyLLM::Tool
- Object
- RubyLLM::Tool
- Insika::Tools::Tts
- Defined in:
- lib/insika/tools/tts.rb
Overview
The agent's SPEECH output (WS9, saída). The engine transports media, never
meaning: the words belong to the customer's channel (a voice note on
WhatsApp), and the contract here just produces the audio bytes and carries
them in the turn's output_parts.
Wired ONLY when both gates pass (ChatBuilder): the agent opted in
(outputs.tts) AND the channel declared it can receive the media
(channel.capabilities includes "audio_output") — nothing leaks by
default. The clip is an envelope part, never part of the answer text;
the turn counts the call in its usage (usage.media) — the provider's
speech API reports no token counts, so the part carries the model for
consumer-side pricing.
Instance Method Summary collapse
- #execute(text:, voice: nil) ⇒ Object
-
#initialize(runner:, config:, state:) ⇒ Tts
constructor
runner: a duck exposing #generate_media_output(:tts, text, config) -> [part, usage] and #account_media_usage(part, usage) (the Executor).
- #name ⇒ Object
Constructor Details
#initialize(runner:, config:, state:) ⇒ Tts
runner: a duck exposing #generate_media_output(:tts, text, config) -> [part, usage] and #account_media_usage(part, usage) (the Executor).
31 32 33 34 35 36 |
# File 'lib/insika/tools/tts.rb', line 31 def initialize(runner:, config:, state:, **) @runner = runner @config = config @state = state super() end |
Instance Method Details
#execute(text:, voice: nil) ⇒ Object
38 39 40 41 42 43 44 |
# File 'lib/insika/tools/tts.rb', line 38 def execute(text:, voice: nil) cfg = @config.merge("voice" => voice.to_s).reject { |_, v| v.to_s.empty? } part, usage = @runner.generate_media_output(:tts, text.to_s, cfg) @state.output_parts << part @runner.account_media_usage(@state, part, usage) "speech synthesized and attached to the reply (#{part["mime_type"]})" end |
#name ⇒ Object
27 |
# File 'lib/insika/tools/tts.rb', line 27 def name = "tts" |