@lumavox/client 0.11.1 → 0.14.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/README.md CHANGED
@@ -57,7 +57,7 @@ for a 402, 403 or 429. `clearToken()` at sign-out.
57
57
  | Resource | Methods |
58
58
  |---|---|
59
59
  | `sessions` | `create`, `list` (every one), `page`, `get`, `history` (the whole transcript, newest first), `delete`, `compact`, `extract` |
60
- | `facts` | `list`, `page`, `delete`, `deleteAll` |
60
+ | `facts` | `list`, `page` (`{ include_replaced: true }` after the options lists the replaced ones too), `create` (tell the agents something; `created` says whether it was new), `update` (correct one's words), `delete`, `deleteAll` |
61
61
  | `relations` | `list`, `page` |
62
62
 
63
63
  Bodies and answers are the API's own JSON, as the API reference shows them;
package/dist/client.d.ts CHANGED
@@ -22,7 +22,7 @@
22
22
  * and later, browsers, React Native.
23
23
  */
24
24
  import { type ConnectOptions, Conversation, type ConversationHandlers } from "./conversation.js";
25
- import type { CompactionInfo, CompactRequest, FactInfo, FactPage, FactsDeleted, MessageInfo, RelationInfo, RelationPage, SessionCreateRequest, SessionDetail, SessionInfo, SessionPage } from "./gen/index.js";
25
+ import type { CompactionInfo, CompactRequest, FactCreateRequest, FactInfo, FactPage, FactsDeleted, FactUpdateRequest, MessageInfo, RelationInfo, RelationPage, SessionCreateRequest, SessionDetail, SessionInfo, SessionPage } from "./gen/index.js";
26
26
  import type { WebSocketConstructor } from "./socket.js";
27
27
  import { type GetToken } from "./token.js";
28
28
  import { type Fetch, type RequestOptions } from "./transport.js";
@@ -77,14 +77,31 @@ export interface Sessions {
77
77
  /** Compact it and extract facts, in one model call. */
78
78
  extract(id: string, options?: RequestOptions): Promise<CompactionInfo>;
79
79
  }
80
+ export interface FactListParams {
81
+ /**
82
+ * Also the facts a later conversation replaced or removed, each with
83
+ * `replaced_at`, until they are deleted 30 days later.
84
+ */
85
+ include_replaced?: boolean;
86
+ }
80
87
  export interface Facts {
81
88
  /** Everything remembered about the person, oldest first, 200 a page. */
82
- list(options?: RequestOptions): AsyncGenerator<FactInfo, void, undefined>;
89
+ list(options?: RequestOptions, params?: FactListParams): AsyncGenerator<FactInfo, void, undefined>;
83
90
  /**
84
91
  * One page of them, 100 by default; `cursor` is the `next_cursor` of the
85
92
  * page before.
86
93
  */
87
- page(options?: RequestOptions, cursor?: string): Promise<FactPage>;
94
+ page(options?: RequestOptions, cursor?: string, params?: FactListParams): Promise<FactPage>;
95
+ /**
96
+ * Tell the agents something about the person: yours (`source`
97
+ * `customer`), never replaced by a conversation. `created` is `false`
98
+ * when a fact already said it.
99
+ */
100
+ create(body: FactCreateRequest, options?: RequestOptions): Promise<FactInfo & {
101
+ created: boolean;
102
+ }>;
103
+ /** Correct one fact's words; the old ones are kept as forgotten. */
104
+ update(id: string, body: FactUpdateRequest, options?: RequestOptions): Promise<FactInfo>;
88
105
  /** Forget one: `true`, or `false` when it is already gone. */
89
106
  delete(id: string, options?: RequestOptions): Promise<boolean>;
90
107
  /** Forget everything about the person: how many facts went. Their conversations stay. */
package/dist/client.js CHANGED
@@ -55,11 +55,10 @@ export function createClient(options) {
55
55
  });
56
56
  const tokens = new Tokens(options.getToken);
57
57
  /** A call with the key, and with a new one once if it is refused. */
58
- async function send(call, request) {
58
+ async function answered(call, request) {
59
59
  const key = await tokens.current();
60
60
  try {
61
- return (await transport.request({ ...call, token: key }, request))
62
- .data;
61
+ return await transport.request({ ...call, token: key }, request);
63
62
  }
64
63
  catch (error) {
65
64
  if (!(error instanceof AuthenticationError))
@@ -68,15 +67,16 @@ export function createClient(options) {
68
67
  status: 401,
69
68
  code: error.code,
70
69
  });
71
- return (await transport.request({ ...call, token: fresh }, request))
72
- .data;
70
+ return await transport.request({ ...call, token: fresh }, request);
73
71
  }
74
72
  }
73
+ /** `answered`'s body. */
74
+ const send = async (call, request) => (await answered(call, request)).data;
75
75
  const sessionPath = (id, rest = "") => `/v1/agent/sessions/${segment(id)}${rest}`;
76
76
  /** One page of the list at `path`. */
77
77
  const read = (path, params = {}, request) => send({ method: "GET", path, query: { ...params } }, request);
78
78
  const page = (params = {}, request) => read("/v1/agent/sessions", params, request);
79
- const factPage = (request, cursor, limit) => read("/v1/agent/facts", { limit, cursor }, request);
79
+ const factPage = (request, cursor, params = {}) => read("/v1/agent/facts", { ...params, cursor }, request);
80
80
  const relationPage = (params = {}, request) => read("/v1/agent/relations", params, request);
81
81
  const get = (id, params = {}, request) => send({ method: "GET", path: sessionPath(id), query: { ...params } }, request);
82
82
  return {
@@ -102,10 +102,15 @@ export function createClient(options) {
102
102
  extract: (id, request) => send({ method: "POST", path: sessionPath(id, "/extract") }, request),
103
103
  },
104
104
  facts: {
105
- list: (request) => pages((cursor) => factPage(request, cursor, PAGE)),
106
- page: factPage,
105
+ list: (request, params = {}) => pages((cursor) => factPage(request, cursor, { ...params, limit: PAGE })),
106
+ page: (request, cursor, params = {}) => factPage(request, cursor, params),
107
107
  delete: (id, request) => done(send({ method: "DELETE", path: `/v1/agent/facts/${segment(id)}` }, request)),
108
108
  deleteAll: (request) => send({ method: "DELETE", path: "/v1/agent/facts" }, request),
109
+ create: async (body, request) => {
110
+ const answer = await answered({ method: "POST", path: "/v1/agent/facts", body }, request);
111
+ return { ...answer.data, created: answer.status === 201 };
112
+ },
113
+ update: (id, body, request) => send({ method: "PATCH", path: `/v1/agent/facts/${segment(id)}`, body }, request),
109
114
  },
110
115
  relations: {
111
116
  list: (params = {}, request) => pages((cursor) => relationPage({ limit: PAGE, ...params, cursor }, request)),
@@ -1 +1 @@
1
- export type { ClientOptions, CompactionInfo, CompactRequest, CompactSessionData, CompactSessionError, CompactSessionErrors, CompactSessionResponse, CompactSessionResponses, CreateSessionData, CreateSessionError, CreateSessionErrors, CreateSessionResponse, CreateSessionResponses, DeleteAllFactsData, DeleteAllFactsError, DeleteAllFactsErrors, DeleteAllFactsResponse, DeleteAllFactsResponses, DeleteFactData, DeleteFactError, DeleteFactErrors, DeleteFactResponse, DeleteFactResponses, DeleteSessionData, DeleteSessionError, DeleteSessionErrors, DeleteSessionResponse, DeleteSessionResponses, ErrorCode, ErrorInfo, ErrorResponse, ExtractSessionFactsData, ExtractSessionFactsError, ExtractSessionFactsErrors, ExtractSessionFactsResponse, ExtractSessionFactsResponses, FactInfo, FactPage, FactsDeleted, GetSessionData, GetSessionError, GetSessionErrors, GetSessionResponse, GetSessionResponses, KnowledgeCitation, KnowledgeLookupInfo, ListFactsData, ListFactsError, ListFactsErrors, ListFactsResponse, ListFactsResponses, ListRelationsData, ListRelationsError, ListRelationsErrors, ListRelationsResponse, ListRelationsResponses, ListSessionsData, ListSessionsError, ListSessionsErrors, ListSessionsResponse, ListSessionsResponses, MessageInfo, MessageKnowledge, MessagePage, MessageSource, MessageToolCall, RelationInfo, RelationPage, SessionCreateRequest, SessionDetail, SessionInfo, SessionPage, ValidationIssue } from './types.gen.js';
1
+ export type { ClientOptions, CompactionInfo, CompactRequest, CompactSessionData, CompactSessionError, CompactSessionErrors, CompactSessionResponse, CompactSessionResponses, CreateFactData, CreateFactError, CreateFactErrors, CreateFactResponse, CreateFactResponses, CreateSessionData, CreateSessionError, CreateSessionErrors, CreateSessionResponse, CreateSessionResponses, DeleteAllFactsData, DeleteAllFactsError, DeleteAllFactsErrors, DeleteAllFactsResponse, DeleteAllFactsResponses, DeleteFactData, DeleteFactError, DeleteFactErrors, DeleteFactResponse, DeleteFactResponses, DeleteSessionData, DeleteSessionError, DeleteSessionErrors, DeleteSessionResponse, DeleteSessionResponses, ErrorCode, ErrorInfo, ErrorResponse, ExtractSessionFactsData, ExtractSessionFactsError, ExtractSessionFactsErrors, ExtractSessionFactsResponse, ExtractSessionFactsResponses, FactCreateRequest, FactInfo, FactPage, FactsDeleted, FactUpdateRequest, GetSessionData, GetSessionError, GetSessionErrors, GetSessionResponse, GetSessionResponses, KnowledgeCitation, KnowledgeLookupInfo, ListFactsData, ListFactsError, ListFactsErrors, ListFactsResponse, ListFactsResponses, ListRelationsData, ListRelationsError, ListRelationsErrors, ListRelationsResponse, ListRelationsResponses, ListSessionsData, ListSessionsError, ListSessionsErrors, ListSessionsResponse, ListSessionsResponses, MessageInfo, MessageKnowledge, MessagePage, MessageSource, MessageToolCall, RelationInfo, RelationPage, SessionCreateRequest, SessionDetail, SessionInfo, SessionPage, UpdateFactData, UpdateFactError, UpdateFactErrors, UpdateFactResponse, UpdateFactResponses, ValidationIssue } from './types.gen.js';
@@ -313,14 +313,50 @@ export type FactInfo = {
313
313
  * Which agent was being talked to when this was learned.
314
314
  */
315
315
  agent_id: string | null;
316
+ /**
317
+ * When a conversation last said it again; `null` for never. The agents see the most recently confirmed first when not every fact fits.
318
+ */
319
+ confirmed_at: string | null;
316
320
  created_at: string;
317
321
  id: string;
322
+ /**
323
+ * When a later conversation replaced or removed it; `null` while it stands. Listed only with `include_replaced=true`.
324
+ */
325
+ replaced_at: string | null;
326
+ /**
327
+ * The fact that replaced it — moved city, changed job — or `null` when it was removed with nothing in its place, or stands.
328
+ */
329
+ replaced_by: string | null;
330
+ /**
331
+ * `person`: recalled by every agent of yours that shares its facts. `agent`: kept to one agent (`agent_id`), which alone recalls it — learnt by an agent whose `facts_scope` is `agent`, or added for that agent.
332
+ */
333
+ scope: 'person' | 'agent';
334
+ /**
335
+ * `conversation`: a reading learnt it. `customer`: you added or corrected it — a later conversation never replaces or removes it.
336
+ */
337
+ source: 'conversation' | 'customer';
318
338
  text: string;
319
339
  /**
320
- * A fact is never edited, only learned or forgotten: the same as `created_at`.
340
+ * When it last changed: its `replaced_at` once replaced, else when you last corrected it, else its `created_at`.
321
341
  */
322
342
  updated_at: string;
323
343
  };
344
+ export type FactCreateRequest = {
345
+ /**
346
+ * What to remember about the person, as one plain statement: "Prefers to be called Sam." At most 500 characters. Never a secret — a password, a code, a card, account or identity number, or a key is refused, since facts are sent to the model on every turn.
347
+ */
348
+ text: string;
349
+ /**
350
+ * Keep it to one agent: only that agent recalls it. Unset or `null`: every agent of yours that shares its facts — and the ones that keep their own, too.
351
+ */
352
+ agent_id?: string | null;
353
+ };
354
+ export type FactUpdateRequest = {
355
+ /**
356
+ * What to remember about the person, as one plain statement: "Prefers to be called Sam." At most 500 characters. Never a secret — a password, a code, a card, account or identity number, or a key is refused, since facts are sent to the model on every turn.
357
+ */
358
+ text: string;
359
+ };
324
360
  export type FactsDeleted = {
325
361
  /**
326
362
  * How many stored facts were deleted.
@@ -649,6 +685,10 @@ export type ListFactsData = {
649
685
  * Optional, and only ever the key's own end user — their `eu_...` id or your own id for them. Anybody else is a 403.
650
686
  */
651
687
  end_user_id?: string;
688
+ /**
689
+ * Also list the facts a later conversation replaced or removed, until they are deleted 30 days later.
690
+ */
691
+ include_replaced?: boolean;
652
692
  /**
653
693
  * How many to answer, 1 to 200.
654
694
  */
@@ -686,6 +726,46 @@ export type ListFactsResponses = {
686
726
  200: FactPage;
687
727
  };
688
728
  export type ListFactsResponse = ListFactsResponses[keyof ListFactsResponses];
729
+ export type CreateFactData = {
730
+ body: FactCreateRequest;
731
+ path?: never;
732
+ query?: never;
733
+ url: '/v1/agent/facts';
734
+ };
735
+ export type CreateFactErrors = {
736
+ /**
737
+ * The request could not be read: malformed JSON
738
+ */
739
+ 400: ErrorResponse;
740
+ /**
741
+ * Missing or invalid credentials
742
+ */
743
+ 401: ErrorResponse;
744
+ /**
745
+ * The key's scopes do not cover this, or it is pinned to agents and `agent_id` names another
746
+ */
747
+ 403: ErrorResponse;
748
+ /**
749
+ * No text, or text that looks like a secret — a password, a code, a card, account or identity number, or a key — which no fact may hold
750
+ */
751
+ 422: ErrorResponse;
752
+ /**
753
+ * Rate limit exceeded
754
+ */
755
+ 429: ErrorResponse;
756
+ };
757
+ export type CreateFactError = CreateFactErrors[keyof CreateFactErrors];
758
+ export type CreateFactResponses = {
759
+ /**
760
+ * The fact that already said it, now yours
761
+ */
762
+ 200: FactInfo;
763
+ /**
764
+ * The fact, remembered
765
+ */
766
+ 201: FactInfo;
767
+ };
768
+ export type CreateFactResponse = CreateFactResponses[keyof CreateFactResponses];
689
769
  export type DeleteFactData = {
690
770
  body?: never;
691
771
  path: {
@@ -724,6 +804,52 @@ export type DeleteFactResponses = {
724
804
  204: void;
725
805
  };
726
806
  export type DeleteFactResponse = DeleteFactResponses[keyof DeleteFactResponses];
807
+ export type UpdateFactData = {
808
+ body: FactUpdateRequest;
809
+ path: {
810
+ fact_id: string;
811
+ };
812
+ query?: never;
813
+ url: '/v1/agent/facts/{fact_id}';
814
+ };
815
+ export type UpdateFactErrors = {
816
+ /**
817
+ * The request could not be read: malformed JSON
818
+ */
819
+ 400: ErrorResponse;
820
+ /**
821
+ * Missing or invalid credentials
822
+ */
823
+ 401: ErrorResponse;
824
+ /**
825
+ * The key is valid but its scopes do not cover this capability
826
+ */
827
+ 403: ErrorResponse;
828
+ /**
829
+ * Unknown fact id
830
+ */
831
+ 404: ErrorResponse;
832
+ /**
833
+ * Replaced by a later conversation, or another fact already says that
834
+ */
835
+ 409: ErrorResponse;
836
+ /**
837
+ * No text, or text that looks like a secret — a password, a code, a card, account or identity number, or a key — which no fact may hold
838
+ */
839
+ 422: ErrorResponse;
840
+ /**
841
+ * Rate limit exceeded
842
+ */
843
+ 429: ErrorResponse;
844
+ };
845
+ export type UpdateFactError = UpdateFactErrors[keyof UpdateFactErrors];
846
+ export type UpdateFactResponses = {
847
+ /**
848
+ * The fact, corrected
849
+ */
850
+ 200: FactInfo;
851
+ };
852
+ export type UpdateFactResponse = UpdateFactResponses[keyof UpdateFactResponses];
727
853
  export type ListRelationsData = {
728
854
  body?: never;
729
855
  path?: never;
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  * own options go last.
9
9
  */
10
10
  export type { AgentAudio } from "./audio.js";
11
- export { type Client, type ClientOptions, createClient, DEFAULT_BASE_URL, type Facts, type RelationListParams, type Relations, type SessionGetParams, type SessionListParams, type Sessions, } from "./client.js";
11
+ export { type Client, type ClientOptions, createClient, DEFAULT_BASE_URL, type FactListParams, type Facts, type RelationListParams, type Relations, type SessionGetParams, type SessionListParams, type Sessions, } from "./client.js";
12
12
  export { type CloseInfo, type ConnectOptions, Conversation, type ConversationHandlers, type ConversationState, type Disconnect, type Dropped, READY_DEADLINE_MS, type Snapshot, type StartAudioOptions, type ToolHandler, type TranscriptOutcome, type TurnOptions, type TurnOutcome, type TurnSnapshot, } from "./conversation.js";
13
13
  export { AuthenticationError, ConflictError, ConnectionError, InsufficientCreditsError, NotFoundError, PermissionError, PlatformError, type PlatformErrorInit, RateLimitError, ServerError, TimeoutError, ValidationError, } from "./errors.js";
14
14
  export type * from "./events.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumavox/client",
3
- "version": "0.11.1",
3
+ "version": "0.14.0",
4
4
  "description": "Talk to Lumavox agents from a browser, a React Native app or Node, with an end user's ephemeral key: conversations on the agent's socket, sessions, memory and relations. Zero dependencies.",
5
5
  "license": "MIT",
6
6
  "type": "module",