@awesomate/sdk 0.62.0 → 0.63.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/index.d.ts +95 -1
- package/dist/index.js +43 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* Docs: https://hub.awesomate.ai/docs/sdk/
|
|
27
27
|
*/
|
|
28
28
|
/** This package's version, sent to the hub with every server call. */
|
|
29
|
-
export declare const VERSION = "0.
|
|
29
|
+
export declare const VERSION = "0.63.0";
|
|
30
30
|
/** Augmented by the generated awesomate.d.ts, so each kind's rows are typed. */
|
|
31
31
|
export interface Kinds {
|
|
32
32
|
}
|
|
@@ -1128,6 +1128,35 @@ export declare class AwesomateClient {
|
|
|
1128
1128
|
* for one already thrown away answers `already: true`.
|
|
1129
1129
|
*/
|
|
1130
1130
|
discard: (id: string) => Promise<EmailDiscarded>;
|
|
1131
|
+
/**
|
|
1132
|
+
* Ask the account's own writing agent for an email. It writes in the business's voice from its
|
|
1133
|
+
* details, lists and past results. It may ask first (`questions`): put them to the person and
|
|
1134
|
+
* call again with the same `brief`, the `sessionId` it gave and `answers`. Otherwise it saves a
|
|
1135
|
+
* draft (new to `topic`, or written over the draft `email`) for a person to approve at
|
|
1136
|
+
* `reviewUrl`; or answers `pending` with a `jobId` for `briefStatus()`. Needs crm:draft and
|
|
1137
|
+
* the copywriter on the account. Each email is one of the month's drafts on Awesomate's AI,
|
|
1138
|
+
* none on the account's own OpenRouter key. No writing agent throws `unavailable` (server code
|
|
1139
|
+
* `no_copywriter`): the owner adds one in the hub.
|
|
1140
|
+
*
|
|
1141
|
+
* @example
|
|
1142
|
+
* let r = await db.emails.brief({ brief: 'A special offer for our list this month', topic: 'news' });
|
|
1143
|
+
* if (r.questions) r = await db.emails.brief({ brief: 'A special offer for our list this month', topic: 'news',
|
|
1144
|
+
* sessionId: r.sessionId, answers: r.questions.map((q) => ({ q: q.q, a: 'A free 30-minute review' })) });
|
|
1145
|
+
* if (r.reviewUrl) console.log(r.summary, r.reviewUrl);
|
|
1146
|
+
*/
|
|
1147
|
+
brief: (input: {
|
|
1148
|
+
brief: string;
|
|
1149
|
+
topic?: string;
|
|
1150
|
+
email?: string;
|
|
1151
|
+
answers?: Array<{
|
|
1152
|
+
q: string;
|
|
1153
|
+
a: string;
|
|
1154
|
+
}>;
|
|
1155
|
+
sessionId?: string;
|
|
1156
|
+
agent?: string;
|
|
1157
|
+
}) => Promise<EmailBrief>;
|
|
1158
|
+
/** The result of a `brief()` that answered `pending`: still `pending`, or the questions or the draft. */
|
|
1159
|
+
briefStatus: (jobId: string) => Promise<EmailBrief>;
|
|
1131
1160
|
};
|
|
1132
1161
|
/**
|
|
1133
1162
|
* Email series: emails that go to one person at a time over days, starting when something
|
|
@@ -1193,6 +1222,21 @@ export declare class AwesomateClient {
|
|
|
1193
1222
|
}) => Promise<EmailSeriesDraft>;
|
|
1194
1223
|
/** Change one email of a series (by its key); the rest of the draft, or what is live, is kept. */
|
|
1195
1224
|
updateEmail: (id: string, key: string, doc: EmailSeriesEmail["doc"]) => Promise<EmailSeriesDraft>;
|
|
1225
|
+
/**
|
|
1226
|
+
* Ask the account's own writing agent to write a series' emails from one brief: every email
|
|
1227
|
+
* still holding a [gap], or every one with `all`. One draft version is saved, never made live:
|
|
1228
|
+
* an approver approves it at `reviewUrl`. A long write answers `pending` with a `jobId` for
|
|
1229
|
+
* `writeStatus()`. Needs crm:draft and the copywriter on the account; each email is one of
|
|
1230
|
+
* the month's drafts on Awesomate's AI. Several writing agents and none named throws `invalid`
|
|
1231
|
+
* (server code `pick_copywriter`).
|
|
1232
|
+
*/
|
|
1233
|
+
write: (id: string, input: {
|
|
1234
|
+
brief: string;
|
|
1235
|
+
all?: boolean;
|
|
1236
|
+
agent?: string;
|
|
1237
|
+
}) => Promise<EmailSeriesWrite>;
|
|
1238
|
+
/** The result of a `write()` that answered `pending`. */
|
|
1239
|
+
writeStatus: (id: string, jobId: string) => Promise<EmailSeriesWrite>;
|
|
1196
1240
|
};
|
|
1197
1241
|
/**
|
|
1198
1242
|
* Sign-up forms: the business's own form on its website that puts each person into Contacts,
|
|
@@ -3376,6 +3420,51 @@ export interface EmailListReach {
|
|
|
3376
3420
|
/** How many are left out, by reason (unsubscribed, bounced, ...). */
|
|
3377
3421
|
leftOut: Record<string, number>;
|
|
3378
3422
|
}
|
|
3423
|
+
/** What `emails.brief()` answers: the agent's questions, a saved draft, or `pending`. */
|
|
3424
|
+
export interface EmailBrief {
|
|
3425
|
+
/** The agent needs these answered first; pass them back as `answers` with this `sessionId`. */
|
|
3426
|
+
questions?: Array<{
|
|
3427
|
+
q: string;
|
|
3428
|
+
choices?: string[];
|
|
3429
|
+
}>;
|
|
3430
|
+
sessionId?: string;
|
|
3431
|
+
/** The draft saved for review. */
|
|
3432
|
+
id?: string;
|
|
3433
|
+
summary?: string;
|
|
3434
|
+
why?: string;
|
|
3435
|
+
reviewUrl?: string;
|
|
3436
|
+
/** Still writing: ask `briefStatus(jobId)`. */
|
|
3437
|
+
pending?: true;
|
|
3438
|
+
jobId?: string;
|
|
3439
|
+
/** This month's drafts on Awesomate's AI. */
|
|
3440
|
+
allowance?: {
|
|
3441
|
+
ownKey: boolean;
|
|
3442
|
+
used: number;
|
|
3443
|
+
limit: number | null;
|
|
3444
|
+
left: number | null;
|
|
3445
|
+
blocked: boolean;
|
|
3446
|
+
};
|
|
3447
|
+
/** What to do next, to tell the owner. */
|
|
3448
|
+
next?: string;
|
|
3449
|
+
}
|
|
3450
|
+
/** What `emailSeries.write()` answers. */
|
|
3451
|
+
export interface EmailSeriesWrite {
|
|
3452
|
+
id?: string;
|
|
3453
|
+
/** How many emails were written and saved. */
|
|
3454
|
+
written?: number;
|
|
3455
|
+
/** The emails that were not, and why. */
|
|
3456
|
+
failed?: Array<{
|
|
3457
|
+
key: string;
|
|
3458
|
+
message: string;
|
|
3459
|
+
}>;
|
|
3460
|
+
/** One sentence for the owner. */
|
|
3461
|
+
sentence?: string;
|
|
3462
|
+
reviewUrl?: string;
|
|
3463
|
+
next?: string;
|
|
3464
|
+
/** Still writing: ask `writeStatus(id, job_id)`. */
|
|
3465
|
+
pending?: true;
|
|
3466
|
+
job_id?: string;
|
|
3467
|
+
}
|
|
3379
3468
|
/** A draft, from `emails.draft()` or `emails.update()`. */
|
|
3380
3469
|
export interface EmailDraft {
|
|
3381
3470
|
id: string;
|
|
@@ -4204,12 +4293,17 @@ export interface KnowledgeAnswer {
|
|
|
4204
4293
|
answer: string | null;
|
|
4205
4294
|
/** True only for an ok answer with sources. An ok answer with none came from the model, not the content. */
|
|
4206
4295
|
grounded: boolean;
|
|
4296
|
+
/**
|
|
4297
|
+
* `watchUrl`: a cited video anyone can watch, its permanent player page at the cited second
|
|
4298
|
+
* (`https://<host>/v/<id>?t=612`). Safe to store or put on a page; null for anything else.
|
|
4299
|
+
*/
|
|
4207
4300
|
sources: Array<{
|
|
4208
4301
|
ref: number;
|
|
4209
4302
|
title: string | null;
|
|
4210
4303
|
kind: string | null;
|
|
4211
4304
|
locator: string | null;
|
|
4212
4305
|
url: string | null;
|
|
4306
|
+
watchUrl: string | null;
|
|
4213
4307
|
}>;
|
|
4214
4308
|
/** What the owner set the assistant to say when it has no answer. */
|
|
4215
4309
|
noAnswerMessage: string | null;
|
package/dist/index.js
CHANGED
|
@@ -26,8 +26,10 @@
|
|
|
26
26
|
* Docs: https://hub.awesomate.ai/docs/sdk/
|
|
27
27
|
*/
|
|
28
28
|
/** This package's version, sent to the hub with every server call. */
|
|
29
|
-
export const VERSION = '0.
|
|
29
|
+
export const VERSION = '0.63.0';
|
|
30
30
|
const DEFAULT_BASE = 'https://hub.awesomate.ai';
|
|
31
|
+
/** The one check for a platform `watch_url` (mirrored in the hub's awesomate-knowledge.ts and its MCP). */
|
|
32
|
+
const WATCH_URL = /^https:\/\/[^\s"'<>]+$/i;
|
|
31
33
|
/** Every record and contact id is a UUID; anything else can name no row. */
|
|
32
34
|
const RECORD_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
33
35
|
const ERROR_CODES = [
|
|
@@ -809,6 +811,30 @@ export class AwesomateClient {
|
|
|
809
811
|
* for one already thrown away answers `already: true`.
|
|
810
812
|
*/
|
|
811
813
|
discard: async (id) => this.request('DELETE', `/api/my-crm/v1/emails/${emailId(id)}`, undefined, false),
|
|
814
|
+
/**
|
|
815
|
+
* Ask the account's own writing agent for an email. It writes in the business's voice from its
|
|
816
|
+
* details, lists and past results. It may ask first (`questions`): put them to the person and
|
|
817
|
+
* call again with the same `brief`, the `sessionId` it gave and `answers`. Otherwise it saves a
|
|
818
|
+
* draft (new to `topic`, or written over the draft `email`) for a person to approve at
|
|
819
|
+
* `reviewUrl`; or answers `pending` with a `jobId` for `briefStatus()`. Needs crm:draft and
|
|
820
|
+
* the copywriter on the account. Each email is one of the month's drafts on Awesomate's AI,
|
|
821
|
+
* none on the account's own OpenRouter key. No writing agent throws `unavailable` (server code
|
|
822
|
+
* `no_copywriter`): the owner adds one in the hub.
|
|
823
|
+
*
|
|
824
|
+
* @example
|
|
825
|
+
* let r = await db.emails.brief({ brief: 'A special offer for our list this month', topic: 'news' });
|
|
826
|
+
* if (r.questions) r = await db.emails.brief({ brief: 'A special offer for our list this month', topic: 'news',
|
|
827
|
+
* sessionId: r.sessionId, answers: r.questions.map((q) => ({ q: q.q, a: 'A free 30-minute review' })) });
|
|
828
|
+
* if (r.reviewUrl) console.log(r.summary, r.reviewUrl);
|
|
829
|
+
*/
|
|
830
|
+
brief: async (input) => {
|
|
831
|
+
const r = await this.request('POST', '/api/my-crm/v1/emails/brief', {
|
|
832
|
+
brief: input.brief, topic: input.topic, email: input.email, answers: input.answers, session_id: input.sessionId, agent: input.agent,
|
|
833
|
+
}, false);
|
|
834
|
+
return briefFromWire(r);
|
|
835
|
+
},
|
|
836
|
+
/** The result of a `brief()` that answered `pending`: still `pending`, or the questions or the draft. */
|
|
837
|
+
briefStatus: async (jobId) => briefFromWire(await this.request('GET', `/api/my-crm/v1/emails/brief/${encodeURIComponent(jobId)}`)),
|
|
812
838
|
};
|
|
813
839
|
/**
|
|
814
840
|
* Email series: emails that go to one person at a time over days, starting when something
|
|
@@ -872,6 +898,17 @@ export class AwesomateClient {
|
|
|
872
898
|
update: (id, input) => this.request('PUT', `/api/my-crm/v1/series/${encodeURIComponent(id)}/draft`, input, false),
|
|
873
899
|
/** Change one email of a series (by its key); the rest of the draft, or what is live, is kept. */
|
|
874
900
|
updateEmail: (id, key, doc) => this.request('PUT', `/api/my-crm/v1/series/${encodeURIComponent(id)}/emails/${encodeURIComponent(key)}`, { doc }, false),
|
|
901
|
+
/**
|
|
902
|
+
* Ask the account's own writing agent to write a series' emails from one brief: every email
|
|
903
|
+
* still holding a [gap], or every one with `all`. One draft version is saved, never made live:
|
|
904
|
+
* an approver approves it at `reviewUrl`. A long write answers `pending` with a `jobId` for
|
|
905
|
+
* `writeStatus()`. Needs crm:draft and the copywriter on the account; each email is one of
|
|
906
|
+
* the month's drafts on Awesomate's AI. Several writing agents and none named throws `invalid`
|
|
907
|
+
* (server code `pick_copywriter`).
|
|
908
|
+
*/
|
|
909
|
+
write: (id, input) => this.request('POST', `/api/my-crm/v1/series/${encodeURIComponent(id)}/write`, input, false),
|
|
910
|
+
/** The result of a `write()` that answered `pending`. */
|
|
911
|
+
writeStatus: (id, jobId) => this.request('GET', `/api/my-crm/v1/series/${encodeURIComponent(id)}/write/${encodeURIComponent(jobId)}`),
|
|
875
912
|
};
|
|
876
913
|
/**
|
|
877
914
|
* Sign-up forms: the business's own form on its website that puts each person into Contacts,
|
|
@@ -1191,6 +1228,7 @@ export class AwesomateClient {
|
|
|
1191
1228
|
kind: typeof s.kind === 'string' ? s.kind : null,
|
|
1192
1229
|
locator: (typeof s.locator === 'string' ? s.locator : typeof s.section_path === 'string' ? s.section_path : null),
|
|
1193
1230
|
url: typeof s.url === 'string' ? s.url : null,
|
|
1231
|
+
watchUrl: typeof s.watch_url === 'string' && WATCH_URL.test(s.watch_url) ? s.watch_url : null,
|
|
1194
1232
|
}));
|
|
1195
1233
|
const text = typeof r.answer_plain === 'string' && r.answer_plain ? r.answer_plain : typeof r.answer === 'string' ? r.answer : null;
|
|
1196
1234
|
return {
|
|
@@ -1701,6 +1739,10 @@ export class AwesomateClient {
|
|
|
1701
1739
|
return { ...r.usage, own_key: r.own_key };
|
|
1702
1740
|
}
|
|
1703
1741
|
}
|
|
1742
|
+
function briefFromWire(r) {
|
|
1743
|
+
const { session_id, job_id, ...rest } = r;
|
|
1744
|
+
return { ...rest, ...(session_id ? { sessionId: session_id } : {}), ...(job_id ? { jobId: job_id } : {}) };
|
|
1745
|
+
}
|
|
1704
1746
|
function memoryStorage() {
|
|
1705
1747
|
const m = new Map();
|
|
1706
1748
|
return { getItem: (k) => m.get(k) ?? null, setItem: (k, v) => { m.set(k, v); }, removeItem: (k) => { m.delete(k); } };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@awesomate/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.63.0",
|
|
4
4
|
"description": "Your own Awesomate data from Node and the browser: query contacts and app data with generated types, and sign your app's own users in",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|