pinecall 0.11.4 → 0.11.6
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 +4 -4
- data/CHANGELOG.md +20 -0
- data/README.md +5 -1
- data/lib/pinecall/agent/config.rb +10 -1
- data/lib/pinecall/client.rb +7 -0
- data/lib/pinecall/rules.rb +2 -1
- data/lib/pinecall/version.rb +1 -1
- data/lib/pinecall/wire/shapes_doors.rb +1 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 66acc2b03dc885f895bb10ccd87704dee937ff8d95424b0e234d1b472e7b5b28
|
|
4
|
+
data.tar.gz: f123a4e58f6bde1752fbf23b7721833d38c1bbe206f04572965ad17e59225c4d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0f4c8e96249c20f53d43f72637856f0252d545b516ca706ef841f998bb8b69b25b15b3d5b9b7705ee635c941d06944499ecab3847850071811772d279ecca6c7
|
|
7
|
+
data.tar.gz: a3354001ed6b79605e0d230e8e145ca362b517c59fdf5f9df870ec561c1cd06f6404134bc669a1a22af455d430f6e77688af71a0dd4eb0fa7f062aa8bac9e47b
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,26 @@ 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
|
+
## [0.11.6] — Released with every other package (2026-10-19)
|
|
8
|
+
|
|
9
|
+
- Nothing of the gem changed: published at 0.11.6 with every other package.
|
|
10
|
+
|
|
11
|
+
## [0.11.5] — realtime: a voice call's model that hears and speaks itself, beside the llm (2026-10-19)
|
|
12
|
+
|
|
13
|
+
- **A voice call runs on a realtime model while a written call keeps the LLM.** `realtime "xai/grok-voice-3.0", options: { voice: "eve" }` names the
|
|
14
|
+
model the agent's voice calls (phone and web) run on alone, one that hears and speaks itself — no
|
|
15
|
+
ears, its own voice — while the `llm` keeps answering its written calls. Its options run on the
|
|
16
|
+
org's own key for the vendor; an `llm` that names such a model is refused at registration.
|
|
17
|
+
|
|
18
|
+
- **An agent an admin killed is declared no more.** An `error` coded `killed` on one agent
|
|
19
|
+
(`POST /v1/agents/{slug}/kill`) drops it from the agents the client declares: the socket stays,
|
|
20
|
+
the other agents go on, and a reconnect leaves the killed one out.
|
|
21
|
+
|
|
22
|
+
- **An agent no longer says it will check and then stops.** The first protocol every agent is given now
|
|
23
|
+
says to call the tool in the same reply, that saying it is about to act does not act, and never to ask
|
|
24
|
+
the caller to wait: once it stops talking nothing happens until the caller speaks. Open models said
|
|
25
|
+
"Let me check the details of your order. Please wait." and ended the turn (2026-10-18).
|
|
26
|
+
|
|
7
27
|
## [0.11.4] — Released with every other package (2026-10-17)
|
|
8
28
|
|
|
9
29
|
- Nothing of the Ruby SDK changed: published at 0.11.4 with every other package.
|
data/README.md
CHANGED
|
@@ -66,7 +66,7 @@ project laid out as `agents/<name>/agent.rb`, with this gem in its `Gemfile`:
|
|
|
66
66
|
```bash
|
|
67
67
|
bundle add pinecall
|
|
68
68
|
npm i -g pinecall # the CLI: Node, whatever the agent is written in
|
|
69
|
-
pinecall
|
|
69
|
+
pinecall login # this machine signed in, once; pinecall.json names the org
|
|
70
70
|
pinecall prompt --state agents/<name>/test/goldens/a.json # the exact prompt a state produces. No gateway.
|
|
71
71
|
pinecall chat # the agent served from this terminal, and a caller against it
|
|
72
72
|
pinecall test # ring 1: the goldens, scored by the gateway
|
|
@@ -99,6 +99,10 @@ agent.on("turn.user") { |data, call| call.say("I heard: #{data[:text]}") }
|
|
|
99
99
|
pc.connect
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
+
`PINECALL_KEY` here is a server's token, made in the console's API keys screen for the org and the
|
|
103
|
+
environment the process runs in — not your own sign-in, which stays on your machine. On a runtime
|
|
104
|
+
of your own the URL is its gateway's (`http://127.0.0.1:8080` on your machine).
|
|
105
|
+
|
|
102
106
|
## Testing it
|
|
103
107
|
|
|
104
108
|
Agent tests run with no network, key, model or gateway:
|
|
@@ -13,7 +13,7 @@ module Pinecall
|
|
|
13
13
|
AS_WRITTEN = %i[phone whatsapp web channel_rules].freeze
|
|
14
14
|
|
|
15
15
|
# The settings a class may declare. Must match the TypeScript package's `ENVIRONMENT`.
|
|
16
|
-
ENVIRONMENT = %i[language voice llm stt judge greeting hangup turn says hears knowledge docs memory record].freeze
|
|
16
|
+
ENVIRONMENT = %i[language voice llm realtime stt judge greeting hangup turn says hears knowledge docs memory record].freeze
|
|
17
17
|
|
|
18
18
|
# The ones written as the wire's own fields, keyword by keyword: `greeting say: "…"`.
|
|
19
19
|
AS_KEYWORDS = %i[turn knowledge docs memory].freeze
|
|
@@ -81,6 +81,15 @@ module Pinecall
|
|
|
81
81
|
environment[:llm] = { **Config.model_of(model), temperature:, builds:, options: }.compact
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
+
# The model a voice call runs on alone, one that hears and speaks itself; a written call
|
|
85
|
+
# keeps the `llm`: `realtime "xai/grok-voice-3.0", options: { voice: "eve" }`. Its options
|
|
86
|
+
# run on the org's own key for the vendor.
|
|
87
|
+
def realtime(model = NOTHING, options: nil)
|
|
88
|
+
return environment[:realtime] if model.equal?(NOTHING)
|
|
89
|
+
|
|
90
|
+
environment[:realtime] = { **Config.model_of(model), options: }.compact
|
|
91
|
+
end
|
|
92
|
+
|
|
84
93
|
# The ears, `vendor/model` or a vendor alone, and who says the caller's turn is over:
|
|
85
94
|
# `end_of_turn: "stt"` the ears themselves (Deepgram Flux), `"livekit"` or `"smart-turn"`.
|
|
86
95
|
def stt(model = NOTHING, builds: nil, options: nil, end_of_turn: nil)
|
data/lib/pinecall/client.rb
CHANGED
|
@@ -33,6 +33,10 @@ module Pinecall
|
|
|
33
33
|
# A stop from the org: the socket is closed for good and the app decides what comes next.
|
|
34
34
|
STOPPED = "stopped"
|
|
35
35
|
|
|
36
|
+
# One agent an admin killed (`POST /v1/agents/{slug}/kill`): the gateway let go of it, and the
|
|
37
|
+
# client declares it no more when it reconnects. The other agents go on.
|
|
38
|
+
KILLED = "killed"
|
|
39
|
+
|
|
36
40
|
# Seconds the running tools are given to answer once a drain was asked.
|
|
37
41
|
TOOLS_FINISH_WITHIN_S = 30
|
|
38
42
|
|
|
@@ -173,11 +177,14 @@ module Pinecall
|
|
|
173
177
|
return if agent.nil?
|
|
174
178
|
|
|
175
179
|
guarded { agent.take(entry) }
|
|
180
|
+
@agents.delete(entry.agent) if killed?(entry)
|
|
176
181
|
end
|
|
177
182
|
|
|
178
183
|
# An `error` coded `stopped` for no agent: a member of the org pressed Stop.
|
|
179
184
|
def stop?(entry) = entry.type == "error" && entry.agent.to_s.empty? && entry.data[:code] == STOPPED
|
|
180
185
|
|
|
186
|
+
def killed?(entry) = entry.type == "error" && entry.data[:code] == KILLED
|
|
187
|
+
|
|
181
188
|
# With no stop listener the stop is reported as an error, so it is never silent.
|
|
182
189
|
# Every agent registered again, then whoever asked to know.
|
|
183
190
|
def opened
|
data/lib/pinecall/rules.rb
CHANGED
|
@@ -13,7 +13,8 @@ module Pinecall
|
|
|
13
13
|
].join("\n").freeze
|
|
14
14
|
|
|
15
15
|
PROTOCOLS = [
|
|
16
|
-
"- To act, call a tool; saying you have done something
|
|
16
|
+
"- To act, call a tool in the same reply; saying you have done something, or that you are about to, " \
|
|
17
|
+
"does not do it. Never ask the caller to wait: once you stop talking, nothing happens until they speak again.",
|
|
17
18
|
"- Before an irreversible action read back what you are about to do and wait for an explicit yes.",
|
|
18
19
|
"- If you cannot solve it, say so and offer to hand over to a person."
|
|
19
20
|
].join("\n").freeze
|
data/lib/pinecall/version.rb
CHANGED
|
@@ -22,6 +22,7 @@ module Pinecall
|
|
|
22
22
|
greeting: { kind: :ref, ref: "GreetingConfig" },
|
|
23
23
|
voice: { kind: :ref, ref: "VoiceConfig" },
|
|
24
24
|
llm: { kind: :ref, ref: "ModelConfig" },
|
|
25
|
+
realtime: { kind: :ref, ref: "ModelConfig" },
|
|
25
26
|
stt: { kind: :ref, ref: "ModelConfig" },
|
|
26
27
|
judge: { kind: :ref, ref: "ModelConfig" },
|
|
27
28
|
turn: { kind: :ref, ref: "TurnConfig" },
|