@stackbone/cli 0.7.1 → 0.9.0
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.
- package/CHANGELOG.md +152 -0
- package/main.js +3593 -1135
- package/migrations/0117_rag_extract_fields.sql +3 -0
- package/migrations/0118_voice_outbound_calls.sql +29 -0
- package/migrations/0119_voice_call_metrics.sql +20 -0
- package/migrations/0120_run_steps_voice.sql +19 -0
- package/migrations/0121_model_routing.sql +28 -0
- package/package.json +1 -1
- package/stackbone-cli-0.9.0.tgz +0 -0
- package/voice-worker/main.js +571 -310
- package/voice-worker/main.js.map +4 -4
- package/stackbone-cli-0.7.1.tgz +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,158 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.9.0] - 2026-11-10
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **The query rewrite is a card on Studio's System screen.**
|
|
15
|
+
`GET /api/internal-prompts` lists the query rewrite that
|
|
16
|
+
`stackbone.rag.retrieve({ rewrite })` runs, with its built-in prompt and the
|
|
17
|
+
model it falls back to: the `defaultModel` workspace setting, else
|
|
18
|
+
`openai/gpt-4o-mini`. Its prompt is edited and published through
|
|
19
|
+
`/api/prompts` like the other System prompts, and `/api/settings` takes
|
|
20
|
+
`rewriteModel` and `rewriteModelProviderId` (STA3-90).
|
|
21
|
+
- **Voice calls play background audio.** The box sends each call's
|
|
22
|
+
`backgroundAudio` voice setting to the voice worker, and the worker, the one
|
|
23
|
+
`stackbone dev` runs too, plays an ambience under the whole call and a
|
|
24
|
+
thinking sound while the agent works on a reply: the knowledge search, the
|
|
25
|
+
wait for the model's first token and any box tool call. Before, only a chime
|
|
26
|
+
played, and only during tool calls. By default a call plays
|
|
27
|
+
`office-ambience` at 0.7 and `keyboard-typing` at 0.6. Studio's Voice tab
|
|
28
|
+
gets a **Background audio** group. Deploy the worker on LiveKit Cloud before
|
|
29
|
+
the boxes: an older worker refuses every call from a box on this release,
|
|
30
|
+
while the new worker takes calls from an older box and plays the defaults.
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
- **A long hybrid query finds the chunks that hold several of its words.**
|
|
35
|
+
`stackbone rag query`, Studio's search dialog and
|
|
36
|
+
`POST /api/rag/collections/{name}/query` used to need every word of the
|
|
37
|
+
query in one chunk, so a long query found nothing by its exact terms. A query
|
|
38
|
+
of up to 3 words still needs all of them. From 4 words on, a chunk needs at
|
|
39
|
+
least 2 of them, `eur` and greetings or sign-offs (`hola`, `gracias`,
|
|
40
|
+
`saludo`, `regards`…) aside, and the chunks that hold more words rank first.
|
|
41
|
+
The response shape does not change. Splitting a text into one search per
|
|
42
|
+
question is an SDK option, `stackbone.rag.retrieve({ rewrite })`, that the box
|
|
43
|
+
route does not take (STA3-79).
|
|
44
|
+
- **On an OpenRouter box a decision model rules on the input guardrails.**
|
|
45
|
+
The content moderation, denied topics and prompt injection checks on a user
|
|
46
|
+
message (chat, voice and workflow input) are decided by `jev-1.13` in one
|
|
47
|
+
request to OpenRouter's `/systemone` endpoint. Each of these rules takes a
|
|
48
|
+
`threshold` from 0 to 1, default 0.7, that a score must reach to stop the
|
|
49
|
+
message; a lower value stops more. A value outside 0 to 1 fails the check.
|
|
50
|
+
The agent's reply is still judged by the checking model, which ignores the
|
|
51
|
+
threshold. When the decision model errors, takes longer than 1.5 seconds or
|
|
52
|
+
leaves a question unscored, the checking model decides and the box log says
|
|
53
|
+
why. A message the decision model stops carries the reason
|
|
54
|
+
`the decision model flagged it`, with no scores. A box on another provider,
|
|
55
|
+
or with no OpenRouter key, checks as before (STA3-58).
|
|
56
|
+
- **The box's own models follow the model provider when nobody picked one.**
|
|
57
|
+
The box lists the models its provider serves at boot and after every
|
|
58
|
+
provider save. The guardrail, eval judge and persona simulator models nobody
|
|
59
|
+
picked run on their code default while the provider serves it or the listing
|
|
60
|
+
has not answered, and on the `defaultModel` workspace setting when the
|
|
61
|
+
provider does not serve it. Studio's System screen shows that default, and the
|
|
62
|
+
memory card shows the one `memory.add` resolves the same way.
|
|
63
|
+
`POST /api/rag/collections` with no embedding model saves
|
|
64
|
+
`openai/text-embedding-3-small` as before, unless the provider does not serve
|
|
65
|
+
it: then the collection gets the first embedding model the provider serves,
|
|
66
|
+
probed for its dimension, and a provider that lists no embedding model
|
|
67
|
+
answers 400 `rag_embedding_model_required`. `stackbone rag collections create`
|
|
68
|
+
sends no embedding model, so it gets the same answer. An OpenRouter box keeps
|
|
69
|
+
today's models, and a model someone picked is never replaced (STA3-82).
|
|
70
|
+
|
|
71
|
+
### Fixed
|
|
72
|
+
|
|
73
|
+
- **Rerank works from creator code in a box.** `retrieve({ rerank })` and
|
|
74
|
+
`client.ai.rerank.create` call the model through the box's model provider
|
|
75
|
+
proxy, which had no `rerank` route and answered 404, so every rerank fell
|
|
76
|
+
back to search order. The proxy now forwards it to the provider's `/rerank`,
|
|
77
|
+
and a model pinned to a provider goes to that provider (STA3-79).
|
|
78
|
+
|
|
79
|
+
## [0.8.0] - 2026-11-06
|
|
80
|
+
|
|
81
|
+
### Added
|
|
82
|
+
|
|
83
|
+
- **`stackbone build` and `dev` record each agent key's `modelRouting`.** The
|
|
84
|
+
model inventory now carries the `modelRouting` literal an agent and each of
|
|
85
|
+
its subagents write, so Studio's Models block shows the code's provider
|
|
86
|
+
routing next to the one an operator picks. A value OpenRouter does not take
|
|
87
|
+
is warned about, with its file and line.
|
|
88
|
+
- **Recurring jobs hides the platform's own timers.** Studio's Recurring jobs
|
|
89
|
+
screen now shows only the workflow crons by default; intake link polling and
|
|
90
|
+
the box's sweeps appear when **System entries** is on, as on Catalog, Runs and
|
|
91
|
+
Sessions. A banner counts the hidden ones that are overdue, not armed or
|
|
92
|
+
failed, so a stuck intake poll still shows. `GET /api/recurring-jobs`
|
|
93
|
+
returns `system` on every row; an older box leaves it out and Studio shows
|
|
94
|
+
the row (STA3-71).
|
|
95
|
+
- `stackbone dev` and `stackbone build` seed the `rag-extract` managed workflow
|
|
96
|
+
for Studio's document value proposals. A creator can override the default in
|
|
97
|
+
`workflows/rag-extract.workflow.ts` (STA3-67).
|
|
98
|
+
- **The box places outbound calls for `placeCall`.** A workflow's `placeCall`
|
|
99
|
+
opens a LiveKit room, dispatches the voice worker and dials the number
|
|
100
|
+
through the trunk in the box secret `LIVEKIT_SIP_OUTBOUND_TRUNK_ID`, with
|
|
101
|
+
`LIVEKIT_SIP_CALLER_ID` as the optional caller id. The agent's model is
|
|
102
|
+
warmed while the phone rings. An answered call is kept until the worker
|
|
103
|
+
reports its end, then the box starts the `onEnd` workflow once. A 30-second
|
|
104
|
+
sweep ends a call as `failed` when its room is gone past a grace period or
|
|
105
|
+
it outlived its call token; the sweep is a system entry on Recurring jobs.
|
|
106
|
+
Migration 0118 adds the calls table (STA3-56).
|
|
107
|
+
- **Each turn of a call is timed on the run that answered it.** The voice
|
|
108
|
+
worker reports the latencies of every answered turn, and the box writes them
|
|
109
|
+
as `voice` steps on that run (**Wait**, then **End of turn**, **Speech to
|
|
110
|
+
text**, **Box**, **Model first token**, **Text to speech** and **Audio
|
|
111
|
+
out**), which Studio draws in the run's trace. Migration 0119 stores the
|
|
112
|
+
latencies and 0120 adds the `voice` step type. `stackbone dev` prints one
|
|
113
|
+
`Voice turn` line per answered turn with the same numbers (STA3-56).
|
|
114
|
+
- **Hybrid search hits say which search found them.**
|
|
115
|
+
`POST /api/rag/collections/{name}/query` returns optional `dense_rank` and
|
|
116
|
+
`lexical_rank` on each hit of a hybrid `text` query: its 1-based position in
|
|
117
|
+
the search by meaning and in the exact-term search, before fusion. A search
|
|
118
|
+
that did not find the hit omits its rank; `hybrid: false`, an `embedding`
|
|
119
|
+
query and an older box return none. `stackbone rag query --json` shows them,
|
|
120
|
+
the table output does not change, and Studio's search dialog labels a hit
|
|
121
|
+
`meaning`, `exact` or `both` (STA3-66).
|
|
122
|
+
- **`rag.previousExchanges` sets how much of the call the knowledge search
|
|
123
|
+
reads.** A voice agent's knowledge search sends the last N exchanges of the
|
|
124
|
+
call (caller question and the reply they heard), oldest first, before the
|
|
125
|
+
caller's sentence. It takes 0 to 5 and defaults to 1, which sends the same
|
|
126
|
+
query as before; 0 searches the sentence alone. Studio's voice settings
|
|
127
|
+
override the code (STA3-76).
|
|
128
|
+
|
|
129
|
+
### Changed
|
|
130
|
+
|
|
131
|
+
- **A voice turn's knowledge search reads the previous exchange.** A follow-up
|
|
132
|
+
such as "¿y los plazos?" names nothing on its own, so the search now carries
|
|
133
|
+
the caller's previous searched question and the reply they heard, after the
|
|
134
|
+
output guardrails. A filler turn, or one that failed before speaking, keeps
|
|
135
|
+
the exchange that held the context (STA3-64).
|
|
136
|
+
- **A voice agent with a knowledge collection only states facts it can
|
|
137
|
+
source.** Every turn of such a call adds a rule to the prompt: a price, date,
|
|
138
|
+
instalment, name or duration comes from the knowledge found for the turn, the
|
|
139
|
+
agent's instructions, a tool result, or an earlier fact of the call the
|
|
140
|
+
caller said or the agent sourced; otherwise the agent tells the caller an
|
|
141
|
+
advisor will confirm it. The rule
|
|
142
|
+
applies even when the search found nothing, and a turn resumed after a tool
|
|
143
|
+
approval keeps it, whether decided in Studio, by the timeout sweep or after a
|
|
144
|
+
box restart. A call without a collection sends the same prompt as before
|
|
145
|
+
(STA3-64).
|
|
146
|
+
- **Voice knowledge search fetches 5 passages by default instead of 3.** At 3,
|
|
147
|
+
a question that asks two things often found the answer to only one
|
|
148
|
+
(STA3-72).
|
|
149
|
+
- **Phone callers get LiveKit's telephony noise model.** Their audio is 8 kHz,
|
|
150
|
+
and the full-band model muffled it and held turns back. With Deepgram Flux
|
|
151
|
+
deciding the turn, the worker now reports how long Flux's decision took to
|
|
152
|
+
reach it as the end of turn, which LiveKit reports as 0 (STA3-56).
|
|
153
|
+
|
|
154
|
+
### Fixed
|
|
155
|
+
|
|
156
|
+
- **A reply blocked by an output guardrail on a voice call speaks the refusal
|
|
157
|
+
phrase.** The caller used to hear the guardrail's reason read aloud. The
|
|
158
|
+
call's `refusalPhrase`, the same one an input guardrail speaks, now replaces
|
|
159
|
+
it; text chat and the run's step keep the reason. A resume with no live call
|
|
160
|
+
keeps the reason, since nobody hears it (STA3-59).
|
|
161
|
+
|
|
10
162
|
## [0.7.1] - 2026-11-04
|
|
11
163
|
|
|
12
164
|
### Added
|