@pinecall/protocol 0.2.0 → 0.3.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.
@@ -52,8 +52,10 @@ export declare const AgentStateChangedSchema: z.ZodObject<{
52
52
  }, z.core.$strict>;
53
53
  export type AgentStateChanged = z.infer<typeof AgentStateChangedSchema>;
54
54
  /**
55
- * Words from the agent as they are played, synced to the audio. Interim while final is false; the
56
- * whole reply becomes turn.agent. Interim entries are ephemeral.
55
+ * One delta of the reply the agent is giving, never the reply so far: in a voice call one word, as
56
+ * the voice plays it, with the seconds it was aligned to; in a written call one model token. The
57
+ * reply so far is every delta of the same speech_id since the last turn.agent, joined; turn.agent
58
+ * carries the whole reply and closes it. Interim entries are ephemeral.
57
59
  */
58
60
  export declare const AgentTranscriptSchema: z.ZodObject<{
59
61
  speech_id: z.ZodString;
@@ -32,8 +32,10 @@ export const AgentStateChangedSchema = z.strictObject({
32
32
  state: AgentStateSchema,
33
33
  });
34
34
  /**
35
- * Words from the agent as they are played, synced to the audio. Interim while final is false; the
36
- * whole reply becomes turn.agent. Interim entries are ephemeral.
35
+ * One delta of the reply the agent is giving, never the reply so far: in a voice call one word, as
36
+ * the voice plays it, with the seconds it was aligned to; in a written call one model token. The
37
+ * reply so far is every delta of the same speech_id since the last turn.agent, joined; turn.agent
38
+ * carries the whole reply and closes it. Interim entries are ephemeral.
37
39
  */
38
40
  export const AgentTranscriptSchema = z.strictObject({
39
41
  speech_id: z.string(),
@@ -991,6 +991,75 @@ export declare const OrgMailWantedSchema: z.ZodObject<{
991
991
  from: z.ZodString;
992
992
  }, z.core.$strict>;
993
993
  export type OrgMailWanted = z.infer<typeof OrgMailWantedSchema>;
994
+ /**
995
+ * GET and PUT /v1/ops/mail: the SMTP account the BOX posts its letters through — what the operator
996
+ * stored, or the environment's two variables — how the last one went, and never the password. An
997
+ * org's own account (OrgMail) still wins over both.
998
+ */
999
+ export declare const BoxMailSchema: z.ZodObject<{
1000
+ configured: z.ZodBoolean;
1001
+ source: z.ZodNullable<z.ZodString>;
1002
+ host: z.ZodNullable<z.ZodString>;
1003
+ port: z.ZodNullable<z.ZodInt>;
1004
+ security: z.ZodNullable<z.ZodString>;
1005
+ username: z.ZodNullable<z.ZodString>;
1006
+ from: z.ZodNullable<z.ZodString>;
1007
+ verified_at: z.ZodNullable<z.ZodString>;
1008
+ last_error: z.ZodNullable<z.ZodString>;
1009
+ }, z.core.$strict>;
1010
+ export type BoxMail = z.infer<typeof BoxMailSchema>;
1011
+ /**
1012
+ * GET and PUT /v1/ops/brand, and `brand` on GET /.well-known/pinecall: what this box's letters and
1013
+ * its sign-in page are called and painted with. Pinecall, its accent and no logo until the
1014
+ * operator says.
1015
+ */
1016
+ export declare const BoxBrandSchema: z.ZodObject<{
1017
+ name: z.ZodString;
1018
+ logo_url: z.ZodNullable<z.ZodString>;
1019
+ accent: z.ZodString;
1020
+ }, z.core.$strict>;
1021
+ export type BoxBrand = z.infer<typeof BoxBrandSchema>;
1022
+ /**
1023
+ * PUT /v1/ops/brand, the body. A field left out keeps what it had; an empty string goes back to
1024
+ * the default — which for the logo is none at all, the only way to clear one.
1025
+ */
1026
+ export declare const BoxBrandWantedSchema: z.ZodObject<{
1027
+ name: z.ZodOptional<z.ZodNullable<z.ZodNullable<z.ZodString>>>;
1028
+ logo_url: z.ZodOptional<z.ZodNullable<z.ZodNullable<z.ZodString>>>;
1029
+ accent: z.ZodOptional<z.ZodNullable<z.ZodNullable<z.ZodString>>>;
1030
+ }, z.core.$strict>;
1031
+ export type BoxBrandWanted = z.infer<typeof BoxBrandWantedSchema>;
1032
+ /**
1033
+ * One box-wide identity provider as the operator reads it: whether it is usable, the client this
1034
+ * gateway is at it, and the URI to register there. Never the secret.
1035
+ */
1036
+ export declare const BoxProviderSchema: z.ZodObject<{
1037
+ configured: z.ZodBoolean;
1038
+ client_id: z.ZodNullable<z.ZodString>;
1039
+ redirect_uri: z.ZodString;
1040
+ }, z.core.$strict>;
1041
+ export type BoxProvider = z.infer<typeof BoxProviderSchema>;
1042
+ /**
1043
+ * GET /v1/ops/signin: every provider this box can offer every org's people, wired or not, one key
1044
+ * each. Only `google` today; a second is a key here and a row on the box.
1045
+ */
1046
+ export declare const BoxSignInSchema: z.ZodObject<{
1047
+ google: z.ZodObject<{
1048
+ configured: z.ZodBoolean;
1049
+ client_id: z.ZodNullable<z.ZodString>;
1050
+ redirect_uri: z.ZodString;
1051
+ }, z.core.$strict>;
1052
+ }, z.core.$strict>;
1053
+ export type BoxSignIn = z.infer<typeof BoxSignInSchema>;
1054
+ /**
1055
+ * PUT /v1/ops/signin/google, the body: the OAuth client the operator made at Google for this
1056
+ * gateway. Replaced whole, the secret write-only; the issuer is Google's own and is not a field.
1057
+ */
1058
+ export declare const BoxProviderWantedSchema: z.ZodObject<{
1059
+ client_id: z.ZodString;
1060
+ client_secret: z.ZodString;
1061
+ }, z.core.$strict>;
1062
+ export type BoxProviderWanted = z.infer<typeof BoxProviderWantedSchema>;
994
1063
  /**
995
1064
  * POST /v1/org/mail/test: one letter, waited for — the only door of this runtime that waits for a
996
1065
  * mail server, because it is the one a person is watching.
@@ -1420,7 +1489,6 @@ export declare const DialGuardsSchema: z.ZodObject<{
1420
1489
  dial_anywhere: z.ZodBoolean;
1421
1490
  per_minute: z.ZodInt;
1422
1491
  per_day: z.ZodInt;
1423
- countries: z.ZodArray<z.ZodString>;
1424
1492
  max_duration_s: z.ZodInt;
1425
1493
  }, z.core.$strict>;
1426
1494
  export type DialGuards = z.infer<typeof DialGuardsSchema>;
@@ -1437,7 +1505,6 @@ export declare const CarrierOutboundSchema: z.ZodObject<{
1437
1505
  dial_anywhere: z.ZodBoolean;
1438
1506
  per_minute: z.ZodInt;
1439
1507
  per_day: z.ZodInt;
1440
- countries: z.ZodArray<z.ZodString>;
1441
1508
  max_duration_s: z.ZodInt;
1442
1509
  }, z.core.$strict>;
1443
1510
  }, z.core.$strict>;
@@ -241,6 +241,65 @@ export const OrgMailWantedSchema = z.strictObject({
241
241
  password: z.string().nullish(),
242
242
  from: z.string(),
243
243
  });
244
+ /**
245
+ * GET and PUT /v1/ops/mail: the SMTP account the BOX posts its letters through — what the operator
246
+ * stored, or the environment's two variables — how the last one went, and never the password. An
247
+ * org's own account (OrgMail) still wins over both.
248
+ */
249
+ export const BoxMailSchema = z.strictObject({
250
+ configured: z.boolean(),
251
+ source: z.string().nullable(),
252
+ host: z.string().nullable(),
253
+ port: z.int().nullable(),
254
+ security: z.string().nullable(),
255
+ username: z.string().nullable(),
256
+ from: z.string().nullable(),
257
+ verified_at: z.string().nullable(),
258
+ last_error: z.string().nullable(),
259
+ });
260
+ /**
261
+ * GET and PUT /v1/ops/brand, and `brand` on GET /.well-known/pinecall: what this box's letters and
262
+ * its sign-in page are called and painted with. Pinecall, its accent and no logo until the
263
+ * operator says.
264
+ */
265
+ export const BoxBrandSchema = z.strictObject({
266
+ name: z.string(),
267
+ logo_url: z.string().nullable(),
268
+ accent: z.string(),
269
+ });
270
+ /**
271
+ * PUT /v1/ops/brand, the body. A field left out keeps what it had; an empty string goes back to
272
+ * the default — which for the logo is none at all, the only way to clear one.
273
+ */
274
+ export const BoxBrandWantedSchema = z.strictObject({
275
+ name: z.string().nullable().nullish(),
276
+ logo_url: z.string().nullable().nullish(),
277
+ accent: z.string().nullable().nullish(),
278
+ });
279
+ /**
280
+ * One box-wide identity provider as the operator reads it: whether it is usable, the client this
281
+ * gateway is at it, and the URI to register there. Never the secret.
282
+ */
283
+ export const BoxProviderSchema = z.strictObject({
284
+ configured: z.boolean(),
285
+ client_id: z.string().nullable(),
286
+ redirect_uri: z.string(),
287
+ });
288
+ /**
289
+ * GET /v1/ops/signin: every provider this box can offer every org's people, wired or not, one key
290
+ * each. Only `google` today; a second is a key here and a row on the box.
291
+ */
292
+ export const BoxSignInSchema = z.strictObject({
293
+ google: BoxProviderSchema,
294
+ });
295
+ /**
296
+ * PUT /v1/ops/signin/google, the body: the OAuth client the operator made at Google for this
297
+ * gateway. Replaced whole, the secret write-only; the issuer is Google's own and is not a field.
298
+ */
299
+ export const BoxProviderWantedSchema = z.strictObject({
300
+ client_id: z.string(),
301
+ client_secret: z.string(),
302
+ });
244
303
  /**
245
304
  * POST /v1/org/mail/test: one letter, waited for — the only door of this runtime that waits for a
246
305
  * mail server, because it is the one a person is watching.
@@ -534,7 +593,6 @@ export const DialGuardsSchema = z.strictObject({
534
593
  dial_anywhere: z.boolean(),
535
594
  per_minute: z.int(),
536
595
  per_day: z.int(),
537
- countries: z.array(z.string()),
538
596
  max_duration_s: z.int(),
539
597
  });
540
598
  /**
package/dist/reduce.js CHANGED
@@ -151,7 +151,8 @@ function applyEvent(state, entry, event) {
151
151
  state.live.user = event.data.final ? null : event.data.text;
152
152
  return;
153
153
  case "agent.transcript":
154
- state.live.agent = event.data.final ? null : event.data.text;
154
+ // A delta, not the reply so far: one word of a spoken reply, one token of a written one.
155
+ state.live.agent = event.data.final ? null : saidSoFar(state.live.agent, event.data);
155
156
  return;
156
157
  case "turn.user":
157
158
  state.turns.push({ role: "user", ...event.data });
@@ -350,3 +351,14 @@ function lastIndex(items, matches) {
350
351
  }
351
352
  return -1;
352
353
  }
354
+ /**
355
+ * The reply in flight with one more delta. A word the voice aligned arrives bare and is set a
356
+ * space apart; a token of a written reply carries its own spacing, and a space glued between
357
+ * "clean" and "ing" would be a word nobody said.
358
+ */
359
+ function saidSoFar(soFar, delta) {
360
+ if (soFar === null || soFar === "")
361
+ return delta.text;
362
+ const apart = /\s$/.test(soFar) || /^\s/.test(delta.text);
363
+ return delta.start != null && !apart ? `${soFar} ${delta.text}` : `${soFar}${delta.text}`;
364
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pinecall/protocol",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "The Pinecall wire: zod schemas and types generated from the protocol schema, and the log reducer",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Pinecall <hello@pinecall.io>",