@persistmemory/sdk 0.1.2 → 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 +3 -0
- package/dist/http.d.ts +20 -0
- package/dist/index.cjs +153 -3
- package/dist/index.cjs.map +3 -3
- package/dist/index.js +153 -3
- package/dist/index.js.map +3 -3
- package/dist/resources/google.d.ts +84 -0
- package/dist/types.d.ts +56 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -238,6 +238,27 @@ var HttpClient = class {
|
|
|
238
238
|
...options ? { options } : {}
|
|
239
239
|
});
|
|
240
240
|
}
|
|
241
|
+
/** POST with a file as the body. The type describes the bytes, not JSON. */
|
|
242
|
+
async postBytes(path, bytes, contentType, query, options) {
|
|
243
|
+
return this.#request({
|
|
244
|
+
method: "POST",
|
|
245
|
+
path,
|
|
246
|
+
rawBody: bytes,
|
|
247
|
+
contentType,
|
|
248
|
+
...query ? { query } : {},
|
|
249
|
+
...options ? { options } : {}
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
/** GET that returns bytes rather than JSON, for downloading a file. */
|
|
253
|
+
async getBytes(path, query, options) {
|
|
254
|
+
return this.#request({
|
|
255
|
+
method: "GET",
|
|
256
|
+
path,
|
|
257
|
+
rawResponse: true,
|
|
258
|
+
...query ? { query } : {},
|
|
259
|
+
...options ? { options } : {}
|
|
260
|
+
});
|
|
261
|
+
}
|
|
241
262
|
async patch(path, body, options) {
|
|
242
263
|
return this.#request({
|
|
243
264
|
method: "PATCH",
|
|
@@ -290,11 +311,20 @@ var HttpClient = class {
|
|
|
290
311
|
this.#fetch(url, {
|
|
291
312
|
method: request.method,
|
|
292
313
|
headers: this.#headers(request),
|
|
293
|
-
...request.body !== void 0 ? { body: JSON.stringify(request.body) } : {},
|
|
314
|
+
...request.rawBody !== void 0 ? { body: request.rawBody } : request.body !== void 0 ? { body: JSON.stringify(request.body) } : {},
|
|
294
315
|
signal: deadline.signal
|
|
295
316
|
}),
|
|
296
317
|
deadline.signal
|
|
297
318
|
);
|
|
319
|
+
if (request.rawResponse && response.ok) {
|
|
320
|
+
const disposition = response.headers.get("content-disposition") ?? "";
|
|
321
|
+
const named = /filename="([^"]+)"/.exec(disposition)?.[1];
|
|
322
|
+
return {
|
|
323
|
+
bytes: new Uint8Array(await response.arrayBuffer()),
|
|
324
|
+
contentType: response.headers.get("content-type") ?? "application/octet-stream",
|
|
325
|
+
...named ? { filename: named } : {}
|
|
326
|
+
};
|
|
327
|
+
}
|
|
298
328
|
const payload = await readBody(response);
|
|
299
329
|
if (!response.ok) throw errorFromResponse(response.status, payload, response.headers);
|
|
300
330
|
return payload;
|
|
@@ -315,9 +345,11 @@ var HttpClient = class {
|
|
|
315
345
|
return {
|
|
316
346
|
// The only place the key is ever read.
|
|
317
347
|
authorization: `Bearer ${this.#apiKey}`,
|
|
318
|
-
|
|
348
|
+
// A download route answers with the file's own type, so `*/*` rather
|
|
349
|
+
// than a promise to accept only JSON that the server would have to break.
|
|
350
|
+
accept: request.rawResponse ? "*/*" : "application/json",
|
|
319
351
|
"user-agent": this.#userAgent,
|
|
320
|
-
...request.body !== void 0 ? { "content-type": "application/json" } : {},
|
|
352
|
+
...request.rawBody !== void 0 ? { "content-type": request.contentType ?? "application/octet-stream" } : request.body !== void 0 ? { "content-type": "application/json" } : {},
|
|
321
353
|
...request.options?.idempotencyKey ? { "idempotency-key": request.options.idempotencyKey } : {}
|
|
322
354
|
};
|
|
323
355
|
}
|
|
@@ -909,6 +941,121 @@ var Conversations = class {
|
|
|
909
941
|
}
|
|
910
942
|
};
|
|
911
943
|
|
|
944
|
+
// src/resources/google.ts
|
|
945
|
+
var Google = class {
|
|
946
|
+
#http;
|
|
947
|
+
constructor(http) {
|
|
948
|
+
this.#http = http;
|
|
949
|
+
}
|
|
950
|
+
/** Files by name, newest first. Omit the query for recently changed ones. */
|
|
951
|
+
async searchDrive(params = {}, options) {
|
|
952
|
+
return this.#http.get(
|
|
953
|
+
"/api/v1/google/drive/files",
|
|
954
|
+
{
|
|
955
|
+
...params.query !== void 0 ? { query: params.query } : {},
|
|
956
|
+
...params.limit !== void 0 ? { limit: params.limit } : {}
|
|
957
|
+
},
|
|
958
|
+
options
|
|
959
|
+
);
|
|
960
|
+
}
|
|
961
|
+
async getDriveFile(fileId, options) {
|
|
962
|
+
return this.#http.get(
|
|
963
|
+
`/api/v1/google/drive/files/${encodeURIComponent(fileId)}`,
|
|
964
|
+
void 0,
|
|
965
|
+
options
|
|
966
|
+
);
|
|
967
|
+
}
|
|
968
|
+
/**
|
|
969
|
+
* The bytes of a Drive file.
|
|
970
|
+
*
|
|
971
|
+
* A Google Doc, Sheet or Slide holds no bytes of its own and is exported on
|
|
972
|
+
* the way - a document as PDF, a spreadsheet as CSV - so `filename` comes
|
|
973
|
+
* back describing what it BECAME. Writing it under the id instead produces a
|
|
974
|
+
* file nothing will open.
|
|
975
|
+
*/
|
|
976
|
+
async downloadDriveFile(fileId, options) {
|
|
977
|
+
return this.#http.getBytes(
|
|
978
|
+
`/api/v1/google/drive/files/${encodeURIComponent(fileId)}/content`,
|
|
979
|
+
void 0,
|
|
980
|
+
options
|
|
981
|
+
);
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* Writes a file into the user's Drive.
|
|
985
|
+
*
|
|
986
|
+
* Needs one of the Drive write permissions on their connection. A read-only
|
|
987
|
+
* grant is refused by Google, and the error names the missing permission
|
|
988
|
+
* rather than reporting a failed upload - one is fixed with a checkbox and
|
|
989
|
+
* the other sends somebody looking for a bug.
|
|
990
|
+
*/
|
|
991
|
+
async saveToDrive(params, options) {
|
|
992
|
+
return this.#http.postBytes(
|
|
993
|
+
"/api/v1/google/drive/files",
|
|
994
|
+
params.bytes,
|
|
995
|
+
params.contentType ?? "application/octet-stream",
|
|
996
|
+
{
|
|
997
|
+
name: params.name,
|
|
998
|
+
...params.folderId !== void 0 ? { folderId: params.folderId } : {}
|
|
999
|
+
},
|
|
1000
|
+
options
|
|
1001
|
+
);
|
|
1002
|
+
}
|
|
1003
|
+
/**
|
|
1004
|
+
* Recent messages - senders, subjects and a one-line preview, never bodies.
|
|
1005
|
+
*
|
|
1006
|
+
* `query` is Gmail's own syntax passed through as written: `from:priya`,
|
|
1007
|
+
* `has:attachment`, `newer_than:7d`. It selects within the connected mailbox
|
|
1008
|
+
* and cannot reach another one.
|
|
1009
|
+
*/
|
|
1010
|
+
async searchMail(params = {}, options) {
|
|
1011
|
+
return this.#http.get(
|
|
1012
|
+
"/api/v1/google/mail",
|
|
1013
|
+
{
|
|
1014
|
+
...params.query !== void 0 ? { query: params.query } : {},
|
|
1015
|
+
...params.limit !== void 0 ? { limit: params.limit } : {}
|
|
1016
|
+
},
|
|
1017
|
+
options
|
|
1018
|
+
);
|
|
1019
|
+
}
|
|
1020
|
+
/** One message, with its body and the names of what is attached. */
|
|
1021
|
+
async readMail(messageId, options) {
|
|
1022
|
+
return this.#http.get(
|
|
1023
|
+
`/api/v1/google/mail/${encodeURIComponent(messageId)}`,
|
|
1024
|
+
void 0,
|
|
1025
|
+
options
|
|
1026
|
+
);
|
|
1027
|
+
}
|
|
1028
|
+
/**
|
|
1029
|
+
* The bytes of one attachment.
|
|
1030
|
+
*
|
|
1031
|
+
* Separate from `readMail` so listing a mailbox never drags attachments
|
|
1032
|
+
* across the network: a message with a 40 MB deck should not cost 40 MB to
|
|
1033
|
+
* summarise.
|
|
1034
|
+
*/
|
|
1035
|
+
async downloadAttachment(messageId, attachmentId, options) {
|
|
1036
|
+
return this.#http.getBytes(
|
|
1037
|
+
`/api/v1/google/mail/${encodeURIComponent(messageId)}/attachments/${encodeURIComponent(attachmentId)}`,
|
|
1038
|
+
void 0,
|
|
1039
|
+
options
|
|
1040
|
+
);
|
|
1041
|
+
}
|
|
1042
|
+
/** Sends as the connected account. Needs the send permission. */
|
|
1043
|
+
async sendMail(params, options) {
|
|
1044
|
+
return this.#http.post("/api/v1/google/mail/send", params, options);
|
|
1045
|
+
}
|
|
1046
|
+
/** People in the user's contacts. Omit the query to list them. */
|
|
1047
|
+
async contacts(params = {}, options) {
|
|
1048
|
+
return this.#http.get(
|
|
1049
|
+
"/api/v1/google/contacts",
|
|
1050
|
+
{
|
|
1051
|
+
...params.query !== void 0 ? { query: params.query } : {},
|
|
1052
|
+
...params.limit !== void 0 ? { limit: params.limit } : {}
|
|
1053
|
+
},
|
|
1054
|
+
options
|
|
1055
|
+
);
|
|
1056
|
+
}
|
|
1057
|
+
};
|
|
1058
|
+
|
|
912
1059
|
// src/resources/integrations.ts
|
|
913
1060
|
var Integrations = class {
|
|
914
1061
|
#http;
|
|
@@ -1046,6 +1193,8 @@ var PersistMemory = class {
|
|
|
1046
1193
|
conflicts;
|
|
1047
1194
|
conversations;
|
|
1048
1195
|
integrations;
|
|
1196
|
+
/** Drive, mail and contacts on the user's connected Google account. */
|
|
1197
|
+
google;
|
|
1049
1198
|
health;
|
|
1050
1199
|
agent;
|
|
1051
1200
|
#http;
|
|
@@ -1062,6 +1211,7 @@ var PersistMemory = class {
|
|
|
1062
1211
|
this.conflicts = new Conflicts(this.#http);
|
|
1063
1212
|
this.conversations = new Conversations(this.#http);
|
|
1064
1213
|
this.integrations = new Integrations(this.#http);
|
|
1214
|
+
this.google = new Google(this.#http);
|
|
1065
1215
|
this.health = new Health(this.#http);
|
|
1066
1216
|
this.agent = new Agent(this.#http);
|
|
1067
1217
|
}
|