@persistmemory/sdk 0.1.1 → 0.2.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/dist/client.d.ts +5 -0
- package/dist/http.d.ts +20 -0
- package/dist/index.cjs +193 -3
- package/dist/index.cjs.map +3 -3
- package/dist/index.js +193 -3
- package/dist/index.js.map +3 -3
- package/dist/resources/agent.d.ts +32 -0
- package/dist/resources/google.d.ts +84 -0
- package/dist/types.d.ts +91 -0
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -5,8 +5,10 @@ import { Spaces } from "./resources/spaces.js";
|
|
|
5
5
|
import { Documents, Jobs, Sources } from "./resources/ingestion.js";
|
|
6
6
|
import { Conflicts, Entities, Graph } from "./resources/knowledge.js";
|
|
7
7
|
import { Conversations } from "./resources/conversations.js";
|
|
8
|
+
import { Google } from "./resources/google.js";
|
|
8
9
|
import { Integrations } from "./resources/integrations.js";
|
|
9
10
|
import { Health } from "./resources/health.js";
|
|
11
|
+
import { Agent } from "./resources/agent.js";
|
|
10
12
|
/**
|
|
11
13
|
* The client.
|
|
12
14
|
*
|
|
@@ -31,7 +33,10 @@ export declare class PersistMemory {
|
|
|
31
33
|
readonly conflicts: Conflicts;
|
|
32
34
|
readonly conversations: Conversations;
|
|
33
35
|
readonly integrations: Integrations;
|
|
36
|
+
/** Drive, mail and contacts on the user's connected Google account. */
|
|
37
|
+
readonly google: Google;
|
|
34
38
|
readonly health: Health;
|
|
39
|
+
readonly agent: Agent;
|
|
35
40
|
constructor(options: ClientOptions);
|
|
36
41
|
/**
|
|
37
42
|
* An escape hatch for an endpoint this package has not caught up with.
|
package/dist/http.d.ts
CHANGED
|
@@ -64,6 +64,18 @@ interface InternalRequest {
|
|
|
64
64
|
readonly path: string;
|
|
65
65
|
readonly query?: QueryParams;
|
|
66
66
|
readonly body?: unknown;
|
|
67
|
+
/**
|
|
68
|
+
* Bytes, for the endpoints that take a file.
|
|
69
|
+
*
|
|
70
|
+
* Separate from `body` rather than sniffed out of it: `JSON.stringify` of a
|
|
71
|
+
* `Uint8Array` produces `{"0":137,"1":80,...}`, which is a valid request and
|
|
72
|
+
* a corrupt file - and the failure shows up as "this PDF is not a PDF" a
|
|
73
|
+
* long way from the line that caused it.
|
|
74
|
+
*/
|
|
75
|
+
readonly rawBody?: Uint8Array;
|
|
76
|
+
readonly contentType?: string;
|
|
77
|
+
/** Bytes back, for a download. JSON is parsed; a file is not. */
|
|
78
|
+
readonly rawResponse?: boolean;
|
|
67
79
|
readonly options?: RequestOptions;
|
|
68
80
|
}
|
|
69
81
|
export declare class HttpClient {
|
|
@@ -80,6 +92,14 @@ export declare class HttpClient {
|
|
|
80
92
|
toJSON(): Record<string, unknown>;
|
|
81
93
|
get<T>(path: string, query?: QueryParams, options?: RequestOptions): Promise<T>;
|
|
82
94
|
post<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
|
|
95
|
+
/** POST with a file as the body. The type describes the bytes, not JSON. */
|
|
96
|
+
postBytes<T>(path: string, bytes: Uint8Array, contentType: string, query?: QueryParams, options?: RequestOptions): Promise<T>;
|
|
97
|
+
/** GET that returns bytes rather than JSON, for downloading a file. */
|
|
98
|
+
getBytes(path: string, query?: QueryParams, options?: RequestOptions): Promise<{
|
|
99
|
+
bytes: Uint8Array;
|
|
100
|
+
contentType: string;
|
|
101
|
+
filename?: string;
|
|
102
|
+
}>;
|
|
83
103
|
patch<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
|
|
84
104
|
delete<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
|
|
85
105
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -279,6 +279,27 @@ var HttpClient = class {
|
|
|
279
279
|
...options ? { options } : {}
|
|
280
280
|
});
|
|
281
281
|
}
|
|
282
|
+
/** POST with a file as the body. The type describes the bytes, not JSON. */
|
|
283
|
+
async postBytes(path, bytes, contentType, query, options) {
|
|
284
|
+
return this.#request({
|
|
285
|
+
method: "POST",
|
|
286
|
+
path,
|
|
287
|
+
rawBody: bytes,
|
|
288
|
+
contentType,
|
|
289
|
+
...query ? { query } : {},
|
|
290
|
+
...options ? { options } : {}
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
/** GET that returns bytes rather than JSON, for downloading a file. */
|
|
294
|
+
async getBytes(path, query, options) {
|
|
295
|
+
return this.#request({
|
|
296
|
+
method: "GET",
|
|
297
|
+
path,
|
|
298
|
+
rawResponse: true,
|
|
299
|
+
...query ? { query } : {},
|
|
300
|
+
...options ? { options } : {}
|
|
301
|
+
});
|
|
302
|
+
}
|
|
282
303
|
async patch(path, body, options) {
|
|
283
304
|
return this.#request({
|
|
284
305
|
method: "PATCH",
|
|
@@ -331,11 +352,20 @@ var HttpClient = class {
|
|
|
331
352
|
this.#fetch(url, {
|
|
332
353
|
method: request.method,
|
|
333
354
|
headers: this.#headers(request),
|
|
334
|
-
...request.body !== void 0 ? { body: JSON.stringify(request.body) } : {},
|
|
355
|
+
...request.rawBody !== void 0 ? { body: request.rawBody } : request.body !== void 0 ? { body: JSON.stringify(request.body) } : {},
|
|
335
356
|
signal: deadline.signal
|
|
336
357
|
}),
|
|
337
358
|
deadline.signal
|
|
338
359
|
);
|
|
360
|
+
if (request.rawResponse && response.ok) {
|
|
361
|
+
const disposition = response.headers.get("content-disposition") ?? "";
|
|
362
|
+
const named = /filename="([^"]+)"/.exec(disposition)?.[1];
|
|
363
|
+
return {
|
|
364
|
+
bytes: new Uint8Array(await response.arrayBuffer()),
|
|
365
|
+
contentType: response.headers.get("content-type") ?? "application/octet-stream",
|
|
366
|
+
...named ? { filename: named } : {}
|
|
367
|
+
};
|
|
368
|
+
}
|
|
339
369
|
const payload = await readBody(response);
|
|
340
370
|
if (!response.ok) throw errorFromResponse(response.status, payload, response.headers);
|
|
341
371
|
return payload;
|
|
@@ -356,9 +386,11 @@ var HttpClient = class {
|
|
|
356
386
|
return {
|
|
357
387
|
// The only place the key is ever read.
|
|
358
388
|
authorization: `Bearer ${this.#apiKey}`,
|
|
359
|
-
|
|
389
|
+
// A download route answers with the file's own type, so `*/*` rather
|
|
390
|
+
// than a promise to accept only JSON that the server would have to break.
|
|
391
|
+
accept: request.rawResponse ? "*/*" : "application/json",
|
|
360
392
|
"user-agent": this.#userAgent,
|
|
361
|
-
...request.body !== void 0 ? { "content-type": "application/json" } : {},
|
|
393
|
+
...request.rawBody !== void 0 ? { "content-type": request.contentType ?? "application/octet-stream" } : request.body !== void 0 ? { "content-type": "application/json" } : {},
|
|
362
394
|
...request.options?.idempotencyKey ? { "idempotency-key": request.options.idempotencyKey } : {}
|
|
363
395
|
};
|
|
364
396
|
}
|
|
@@ -950,6 +982,121 @@ var Conversations = class {
|
|
|
950
982
|
}
|
|
951
983
|
};
|
|
952
984
|
|
|
985
|
+
// src/resources/google.ts
|
|
986
|
+
var Google = class {
|
|
987
|
+
#http;
|
|
988
|
+
constructor(http) {
|
|
989
|
+
this.#http = http;
|
|
990
|
+
}
|
|
991
|
+
/** Files by name, newest first. Omit the query for recently changed ones. */
|
|
992
|
+
async searchDrive(params = {}, options) {
|
|
993
|
+
return this.#http.get(
|
|
994
|
+
"/api/v1/google/drive/files",
|
|
995
|
+
{
|
|
996
|
+
...params.query !== void 0 ? { query: params.query } : {},
|
|
997
|
+
...params.limit !== void 0 ? { limit: params.limit } : {}
|
|
998
|
+
},
|
|
999
|
+
options
|
|
1000
|
+
);
|
|
1001
|
+
}
|
|
1002
|
+
async getDriveFile(fileId, options) {
|
|
1003
|
+
return this.#http.get(
|
|
1004
|
+
`/api/v1/google/drive/files/${encodeURIComponent(fileId)}`,
|
|
1005
|
+
void 0,
|
|
1006
|
+
options
|
|
1007
|
+
);
|
|
1008
|
+
}
|
|
1009
|
+
/**
|
|
1010
|
+
* The bytes of a Drive file.
|
|
1011
|
+
*
|
|
1012
|
+
* A Google Doc, Sheet or Slide holds no bytes of its own and is exported on
|
|
1013
|
+
* the way - a document as PDF, a spreadsheet as CSV - so `filename` comes
|
|
1014
|
+
* back describing what it BECAME. Writing it under the id instead produces a
|
|
1015
|
+
* file nothing will open.
|
|
1016
|
+
*/
|
|
1017
|
+
async downloadDriveFile(fileId, options) {
|
|
1018
|
+
return this.#http.getBytes(
|
|
1019
|
+
`/api/v1/google/drive/files/${encodeURIComponent(fileId)}/content`,
|
|
1020
|
+
void 0,
|
|
1021
|
+
options
|
|
1022
|
+
);
|
|
1023
|
+
}
|
|
1024
|
+
/**
|
|
1025
|
+
* Writes a file into the user's Drive.
|
|
1026
|
+
*
|
|
1027
|
+
* Needs one of the Drive write permissions on their connection. A read-only
|
|
1028
|
+
* grant is refused by Google, and the error names the missing permission
|
|
1029
|
+
* rather than reporting a failed upload - one is fixed with a checkbox and
|
|
1030
|
+
* the other sends somebody looking for a bug.
|
|
1031
|
+
*/
|
|
1032
|
+
async saveToDrive(params, options) {
|
|
1033
|
+
return this.#http.postBytes(
|
|
1034
|
+
"/api/v1/google/drive/files",
|
|
1035
|
+
params.bytes,
|
|
1036
|
+
params.contentType ?? "application/octet-stream",
|
|
1037
|
+
{
|
|
1038
|
+
name: params.name,
|
|
1039
|
+
...params.folderId !== void 0 ? { folderId: params.folderId } : {}
|
|
1040
|
+
},
|
|
1041
|
+
options
|
|
1042
|
+
);
|
|
1043
|
+
}
|
|
1044
|
+
/**
|
|
1045
|
+
* Recent messages - senders, subjects and a one-line preview, never bodies.
|
|
1046
|
+
*
|
|
1047
|
+
* `query` is Gmail's own syntax passed through as written: `from:priya`,
|
|
1048
|
+
* `has:attachment`, `newer_than:7d`. It selects within the connected mailbox
|
|
1049
|
+
* and cannot reach another one.
|
|
1050
|
+
*/
|
|
1051
|
+
async searchMail(params = {}, options) {
|
|
1052
|
+
return this.#http.get(
|
|
1053
|
+
"/api/v1/google/mail",
|
|
1054
|
+
{
|
|
1055
|
+
...params.query !== void 0 ? { query: params.query } : {},
|
|
1056
|
+
...params.limit !== void 0 ? { limit: params.limit } : {}
|
|
1057
|
+
},
|
|
1058
|
+
options
|
|
1059
|
+
);
|
|
1060
|
+
}
|
|
1061
|
+
/** One message, with its body and the names of what is attached. */
|
|
1062
|
+
async readMail(messageId, options) {
|
|
1063
|
+
return this.#http.get(
|
|
1064
|
+
`/api/v1/google/mail/${encodeURIComponent(messageId)}`,
|
|
1065
|
+
void 0,
|
|
1066
|
+
options
|
|
1067
|
+
);
|
|
1068
|
+
}
|
|
1069
|
+
/**
|
|
1070
|
+
* The bytes of one attachment.
|
|
1071
|
+
*
|
|
1072
|
+
* Separate from `readMail` so listing a mailbox never drags attachments
|
|
1073
|
+
* across the network: a message with a 40 MB deck should not cost 40 MB to
|
|
1074
|
+
* summarise.
|
|
1075
|
+
*/
|
|
1076
|
+
async downloadAttachment(messageId, attachmentId, options) {
|
|
1077
|
+
return this.#http.getBytes(
|
|
1078
|
+
`/api/v1/google/mail/${encodeURIComponent(messageId)}/attachments/${encodeURIComponent(attachmentId)}`,
|
|
1079
|
+
void 0,
|
|
1080
|
+
options
|
|
1081
|
+
);
|
|
1082
|
+
}
|
|
1083
|
+
/** Sends as the connected account. Needs the send permission. */
|
|
1084
|
+
async sendMail(params, options) {
|
|
1085
|
+
return this.#http.post("/api/v1/google/mail/send", params, options);
|
|
1086
|
+
}
|
|
1087
|
+
/** People in the user's contacts. Omit the query to list them. */
|
|
1088
|
+
async contacts(params = {}, options) {
|
|
1089
|
+
return this.#http.get(
|
|
1090
|
+
"/api/v1/google/contacts",
|
|
1091
|
+
{
|
|
1092
|
+
...params.query !== void 0 ? { query: params.query } : {},
|
|
1093
|
+
...params.limit !== void 0 ? { limit: params.limit } : {}
|
|
1094
|
+
},
|
|
1095
|
+
options
|
|
1096
|
+
);
|
|
1097
|
+
}
|
|
1098
|
+
};
|
|
1099
|
+
|
|
953
1100
|
// src/resources/integrations.ts
|
|
954
1101
|
var Integrations = class {
|
|
955
1102
|
#http;
|
|
@@ -1036,6 +1183,44 @@ var Health = class {
|
|
|
1036
1183
|
}
|
|
1037
1184
|
};
|
|
1038
1185
|
|
|
1186
|
+
// src/resources/agent.ts
|
|
1187
|
+
var Agent = class {
|
|
1188
|
+
#http;
|
|
1189
|
+
constructor(http) {
|
|
1190
|
+
this.#http = http;
|
|
1191
|
+
}
|
|
1192
|
+
/** The row, including whether it finished and how large the result is. */
|
|
1193
|
+
async request(id, options) {
|
|
1194
|
+
return this.#http.get(
|
|
1195
|
+
`/api/v1/agent/request/${encodeURIComponent(id)}`,
|
|
1196
|
+
void 0,
|
|
1197
|
+
options
|
|
1198
|
+
);
|
|
1199
|
+
}
|
|
1200
|
+
/**
|
|
1201
|
+
* A short-lived link to the bytes of a finished request.
|
|
1202
|
+
*
|
|
1203
|
+
* Returns the URL rather than the file, and that is a deliberate limit of
|
|
1204
|
+
* this package rather than an oversight. The transport under every other
|
|
1205
|
+
* method parses JSON, retries, and attaches the API key; none of those is
|
|
1206
|
+
* right for a hundred-megabyte binary body, and building a second request
|
|
1207
|
+
* path inside the SDK to serve one method is how a client ends up with two
|
|
1208
|
+
* retry policies that differ only during an outage. Fetch the URL with
|
|
1209
|
+
* whatever already streams in your runtime - it needs no credential, which
|
|
1210
|
+
* is the whole reason it is signed.
|
|
1211
|
+
*
|
|
1212
|
+
* Treat the URL as the file. It is a bearer credential for exactly one
|
|
1213
|
+
* object, it expires in minutes, and it should not be logged or stored.
|
|
1214
|
+
*/
|
|
1215
|
+
async downloadLink(id, options) {
|
|
1216
|
+
return this.#http.get(
|
|
1217
|
+
`/api/v1/agent/request/${encodeURIComponent(id)}/download`,
|
|
1218
|
+
void 0,
|
|
1219
|
+
options
|
|
1220
|
+
);
|
|
1221
|
+
}
|
|
1222
|
+
};
|
|
1223
|
+
|
|
1039
1224
|
// src/client.ts
|
|
1040
1225
|
var PersistMemory = class {
|
|
1041
1226
|
memories;
|
|
@@ -1049,7 +1234,10 @@ var PersistMemory = class {
|
|
|
1049
1234
|
conflicts;
|
|
1050
1235
|
conversations;
|
|
1051
1236
|
integrations;
|
|
1237
|
+
/** Drive, mail and contacts on the user's connected Google account. */
|
|
1238
|
+
google;
|
|
1052
1239
|
health;
|
|
1240
|
+
agent;
|
|
1053
1241
|
#http;
|
|
1054
1242
|
constructor(options) {
|
|
1055
1243
|
this.#http = new HttpClient(options);
|
|
@@ -1064,7 +1252,9 @@ var PersistMemory = class {
|
|
|
1064
1252
|
this.conflicts = new Conflicts(this.#http);
|
|
1065
1253
|
this.conversations = new Conversations(this.#http);
|
|
1066
1254
|
this.integrations = new Integrations(this.#http);
|
|
1255
|
+
this.google = new Google(this.#http);
|
|
1067
1256
|
this.health = new Health(this.#http);
|
|
1257
|
+
this.agent = new Agent(this.#http);
|
|
1068
1258
|
}
|
|
1069
1259
|
/**
|
|
1070
1260
|
* An escape hatch for an endpoint this package has not caught up with.
|