pinecall 0.11.20 → 0.11.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 92fa7d36f3fea184946e3f008f6bb5c3af02036ec34c0d98c668057d5d0026dc
4
- data.tar.gz: a9d00558ca5de5bd5c7458d0dbae44c9400fee3071aa13705042d6eb380111b0
3
+ metadata.gz: f69d47743412da64cc63fde25f84698b2d956b746a18fdf7b386f91de0a71af1
4
+ data.tar.gz: 39228564448fddccb6d58528ac06df22e56e5fef66d5955823cf405d234cf41b
5
5
  SHA512:
6
- metadata.gz: 3aee7697d3c30fe185597092ab61435e14368adac8cacd8effb3fcfe987057f3a3fef6b181a9b01bce201f2f39e9f70da0b779e5fa15d62424ce5fbb024f3037
7
- data.tar.gz: 00dcd1199414dcfabb589a52114f2e44997368a1e9707c3dc5d45c4aefcc8e583785faa0a64759b64a426175234ca4ecbf49038753eb518d7be33f214147a60d
6
+ metadata.gz: 78569b72357c0e3cdc2d82cd7dfcc7f55a89212fbcbfa2fdfe494c8a8613df1e67a589c245d8feca87a18a2be01b3ddf8f5492c2b17a8dda2546ab8c62f498ee
7
+ data.tar.gz: 737ee767f0139182c3916601be8eb328273a310e4283d753b89048f94674da6819035d54c9bf76f76d71244ce5c27689ab64f251e75e014feac26c4d38dd384e
data/CHANGELOG.md CHANGED
@@ -4,6 +4,20 @@ Every change a person using this gem would notice. The format is
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version numbers and tags are the
5
5
  maintainer's call.
6
6
 
7
+ ## [Unreleased]
8
+
9
+ ## [0.11.21] — released with the tutor's walks (2026-10-25)
10
+
11
+ - **`call.participant(id).mute` works**: it sent a `muted:` field `participant.mute` does not have, and
12
+ the gateway refused every one. The wire has no unmute. (2026-10-24 tools eval, R F5)
13
+ - **A view that names what nothing answers says the name**, in the log and on the terminal, instead of
14
+ Ruby's NameError with the view's context inspected — the state's private values among it. (R F6)
15
+ - **A class refused as it loads is one sentence through `pinecall start` and `prompt`**, exit 2, never a
16
+ backtrace; an option `tool` does not take is refused as `tool takes no …`. (R F19 · R F1)
17
+ - **The view's `resumed` is true on a call handed over mid-conversation**, and `remembers?` matches case
18
+ aside, as in every SDK.
19
+ - `docs/writing-an-agent.md`: every refusal at load, the ones past the table's seven included. (R F1)
20
+
7
21
  ## [0.11.20] — released with the runtime's live readers (2026-10-24)
8
22
 
9
23
  - Nothing of the gem changed: published at 0.11.20 with every other package.
@@ -24,7 +24,7 @@ module Pinecall
24
24
  # @param params [Hash{Symbol=>Object}] parameter types, e.g. `{ day: String, how_many: Integer }`
25
25
  def tool(**options)
26
26
  unknown = options.keys - %i[when stage confirm announce preview pii timeout params doc]
27
- raise DeclarationRefused, "@tool takes no #{unknown.join(", ")}" unless unknown.empty?
27
+ raise DeclarationRefused, "tool takes no #{unknown.join(", ")}" unless unknown.empty?
28
28
 
29
29
  @pending_tool = options
30
30
  end
@@ -22,8 +22,9 @@ module Pinecall
22
22
  # One served call: its instance, what was last sent, and a thread running its jobs in order.
23
23
  class Live
24
24
  attr_reader :agent, :world, :sent, :stops
25
- # What memory recalled about this caller in this call: what `remembers?` answers from.
26
- attr_accessor :tools_shown, :remembered
25
+ # What memory recalled about this caller in this call: what `remembers?` answers from; and whether
26
+ # the call was handed over mid-conversation, the view's `resumed`.
27
+ attr_accessor :tools_shown, :remembered, :resumed
27
28
 
28
29
  def initialize(agent, world)
29
30
  @agent = agent
@@ -31,6 +32,7 @@ module Pinecall
31
32
  @sent = {}
32
33
  @tools_shown = nil
33
34
  @remembered = []
35
+ @resumed = false
34
36
  @stops = {}
35
37
  @work = Thread::Queue.new
36
38
  @thread = Thread.new { work }
@@ -100,6 +102,7 @@ module Pinecall
100
102
  instance = klass.new.seal
101
103
  instance.reads_last_from(last) unless last.nil?
102
104
  serving = Live.new(instance, world_for(call, client))
105
+ serving.resumed = true
103
106
  instance.serving(serving.world)
104
107
  live[call.id] = serving
105
108
  serving.later do
@@ -250,7 +253,7 @@ module Pinecall
250
253
  def sync(serving, call)
251
254
  line = { channel: call.channel || "web", from: call.from, claimed: serving.world.claimed }
252
255
  begin
253
- rendered = Prompt.render(serving.agent, remembered: serving.remembered, line:)
256
+ rendered = Prompt.render(serving.agent, resumed: serving.resumed, remembered: serving.remembered, line:)
254
257
  visible = serving.agent.visible_tools
255
258
  rescue StandardError => e
256
259
  return failed_to_render(call, e)
@@ -269,8 +272,26 @@ module Pinecall
269
272
 
270
273
  # A view that fails fails its call, never the process: the model keeps the view it had, and the log says why.
271
274
  def failed_to_render(call, error)
272
- call.log("render.failed", { error: error.class.to_s, message: error.message })
273
- warn("pinecall: #{call.id} could not render its view and goes on with the one it had: #{error.message}")
275
+ said = failure_of(error)
276
+ call.log("render.failed", { error: error.class.to_s, message: said })
277
+ warn("pinecall: #{call.id} could not render its view and goes on with the one it had: #{said}")
278
+ end
279
+
280
+ # A NameError's message is Ruby's, with the view's whole context inspected, its state's private values
281
+ # among them (R F6): the name it missed is the sentence, which a person can act on.
282
+ def failure_of(error)
283
+ case error
284
+ when NoMethodError then "the view calls #{error.name} on #{receiver_of(error)}, which does not answer it"
285
+ when NameError then "the view names #{error.name}, which is no field of the state, no call and no method of the class"
286
+ else error.message
287
+ end
288
+ end
289
+
290
+ # The class of what the method was called on (nil, most often): the value itself may be private.
291
+ def receiver_of(error)
292
+ error.receiver.nil? ? "nil" : error.receiver.class.to_s
293
+ rescue ArgumentError
294
+ "something"
274
295
  end
275
296
 
276
297
  # A hook that raises fails its call, never the process: the call goes on with what the hook wrote
@@ -17,7 +17,8 @@ module Pinecall
17
17
  @send = send
18
18
  end
19
19
 
20
- def mute(muted: true) = @send.call("participant.mute", { identity: @identity, muted: })
20
+ # For the rest of the call: the wire has no unmute (`participant.mute` carries the identity alone).
21
+ def mute = @send.call("participant.mute", { identity: @identity })
21
22
 
22
23
  def remove = @send.call("participant.remove", { identity: @identity })
23
24
  end
@@ -20,7 +20,8 @@ module Pinecall
20
20
 
21
21
  # Whether a remembered fact contains `text`. Views may branch on facts but never print them;
22
22
  # facts reach the model only as tool results.
23
- def remembers?(text) = @remembered.any? { |fact| fact.to_s.include?(text.to_s) }
23
+ # Case aside, as in every SDK: "usual doctor" is in "Usual doctor is Dr. Vidal.".
24
+ def remembers?(text) = @remembered.any? { |fact| fact.to_s.downcase.include?(text.to_s.downcase) }
24
25
 
25
26
  def respond_to_missing?(name, include_private = false)
26
27
  @state.key?(name) || super
@@ -32,7 +32,8 @@ module Pinecall
32
32
  when "prompt" then prompt(Loading.parse(rest), out:)
33
33
  else err.puts(USAGE) || 2
34
34
  end
35
- rescue CannotServe, NotConnected, Refused => e
35
+ # A class refused as it loads is one sentence too, never a backtrace (R F19).
36
+ rescue CannotServe, NotConnected, Refused, DeclarationRefused => e
36
37
  err.puts(e.message)
37
38
  2
38
39
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Pinecall
4
4
  # Set by the maintainer at release time.
5
- VERSION = "0.11.20"
5
+ VERSION = "0.11.21"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pinecall
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.20
4
+ version: 0.11.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pinecall