@godwit/sdk 0.0.0-stage → 1.6.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/godwit.d.ts +252 -0
- package/package.json +17 -4
- package/README.md +0 -3
package/godwit.d.ts
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
// @godwit/sdk: types for Godwit plugins (spec 5.3). Types only; import them
|
|
2
|
+
// with `import type { Ctx } from "@godwit/sdk"`. The host provides no way to
|
|
3
|
+
// send mail.
|
|
4
|
+
|
|
5
|
+
/** A label: a plain string, or a default plus translations by language tag. */
|
|
6
|
+
export type Text = string | ({ default: string } & { [lang: string]: string })
|
|
7
|
+
|
|
8
|
+
export interface AttachmentMeta {
|
|
9
|
+
name: string
|
|
10
|
+
type: string
|
|
11
|
+
size: number
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface MailMessage {
|
|
15
|
+
id: number
|
|
16
|
+
subject: string
|
|
17
|
+
from: string
|
|
18
|
+
to: string[]
|
|
19
|
+
cc: string[]
|
|
20
|
+
/** RFC 3339 */
|
|
21
|
+
date: string
|
|
22
|
+
text: string
|
|
23
|
+
html: string
|
|
24
|
+
/** text or html was cut to the host's limit */
|
|
25
|
+
truncated: boolean
|
|
26
|
+
attachments: AttachmentMeta[]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface MailSummary {
|
|
30
|
+
id: number
|
|
31
|
+
subject: string
|
|
32
|
+
from: string
|
|
33
|
+
/** RFC 3339 */
|
|
34
|
+
date: string
|
|
35
|
+
snippet: string
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface DraftInput {
|
|
39
|
+
accountId: number
|
|
40
|
+
to: string[]
|
|
41
|
+
cc?: string[]
|
|
42
|
+
subject: string
|
|
43
|
+
html: string
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface DraftUpdate {
|
|
47
|
+
draftId: number
|
|
48
|
+
/** the revision read; a draft changed since then is not updated */
|
|
49
|
+
revision: number
|
|
50
|
+
html: string
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** The new message a message.received handler gets. */
|
|
54
|
+
export interface ReceivedMessage {
|
|
55
|
+
id: number
|
|
56
|
+
accountId: number
|
|
57
|
+
subject: string
|
|
58
|
+
from: string
|
|
59
|
+
/** RFC 3339 */
|
|
60
|
+
date: string
|
|
61
|
+
/** the message was deleted before delivery; id is still given */
|
|
62
|
+
deleted: boolean
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface DeliveryInfo {
|
|
66
|
+
/** the same on every redelivery of this event */
|
|
67
|
+
idempotencyKey: string
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** The draft a message.beforeSend handler checks. */
|
|
71
|
+
export interface OutgoingDraft {
|
|
72
|
+
id: number
|
|
73
|
+
accountId: number
|
|
74
|
+
to: string[]
|
|
75
|
+
cc: string[]
|
|
76
|
+
subject: string
|
|
77
|
+
html: string
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** warn: the user may still send. block: the user must edit the draft or disable the plugin. */
|
|
81
|
+
export type SendCheck = { warn: string } | { block: string }
|
|
82
|
+
|
|
83
|
+
type MaybePromise<T> = T | Promise<T>
|
|
84
|
+
|
|
85
|
+
export type ActionOn = "message" | "thread" | "selection" | "draft"
|
|
86
|
+
|
|
87
|
+
export interface ActionTarget {
|
|
88
|
+
kind: ActionOn
|
|
89
|
+
id: number
|
|
90
|
+
/** the selected text, for "selection" */
|
|
91
|
+
text?: string
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export type ActionResult = string | { text?: string; html?: string; draftId?: number } | void
|
|
95
|
+
|
|
96
|
+
export interface Action {
|
|
97
|
+
id: string
|
|
98
|
+
label: Text
|
|
99
|
+
on: ActionOn[]
|
|
100
|
+
run(target: ActionTarget): MaybePromise<ActionResult>
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface CardField {
|
|
104
|
+
label: string
|
|
105
|
+
value: string
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface CardButton {
|
|
109
|
+
label: string
|
|
110
|
+
/** copy: value is copied; open-url: value is an http(s) URL; run-action: value is an action id of this plugin */
|
|
111
|
+
kind: "copy" | "open-url" | "run-action"
|
|
112
|
+
value: string
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Declarative card data; the client renders it. */
|
|
116
|
+
export interface Card {
|
|
117
|
+
title: string
|
|
118
|
+
fields?: CardField[]
|
|
119
|
+
buttons?: CardButton[]
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface CardProvider {
|
|
123
|
+
match(message: MailMessage): MaybePromise<boolean>
|
|
124
|
+
render(message: MailMessage): MaybePromise<Card>
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export interface Tool {
|
|
128
|
+
/** ^[a-z][a-z0-9_]{0,40}$ */
|
|
129
|
+
name: string
|
|
130
|
+
description: string
|
|
131
|
+
/** JSON Schema of the arguments */
|
|
132
|
+
schema: Record<string, unknown>
|
|
133
|
+
/** default true: every call is approved by the user first */
|
|
134
|
+
write?: boolean
|
|
135
|
+
run(args: Record<string, unknown>): MaybePromise<unknown>
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export interface FetchInit {
|
|
139
|
+
method?: string
|
|
140
|
+
headers?: Record<string, string>
|
|
141
|
+
body?: string
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export interface FetchResponse {
|
|
145
|
+
status: number
|
|
146
|
+
headers: Record<string, string>
|
|
147
|
+
text(): Promise<string>
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export interface Mail {
|
|
151
|
+
get(id: number): Promise<MailMessage>
|
|
152
|
+
/** at most 50 results */
|
|
153
|
+
search(query: string, limit?: number): Promise<MailSummary[]>
|
|
154
|
+
setFlags(ids: number[], add: string[], remove: string[]): Promise<void>
|
|
155
|
+
move(ids: number[], folderId: number): Promise<void>
|
|
156
|
+
/** returns the new draft's id */
|
|
157
|
+
createDraft(draft: DraftInput): Promise<number>
|
|
158
|
+
/** returns the draft's new revision */
|
|
159
|
+
updateDraft(update: DraftUpdate): Promise<number>
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* a typed question for llm.decide, in the OpenAI Decisions API's shape whatever judge answers;
|
|
164
|
+
* name matches ^[a-z][a-z0-9_]{0,40}$
|
|
165
|
+
*/
|
|
166
|
+
export type Question =
|
|
167
|
+
| { name: string; type: "predicate"; instructions: string }
|
|
168
|
+
/** 2 to 255 unique values */
|
|
169
|
+
| { name: string; type: "choice"; instructions: string; choices: ChoiceOption[] }
|
|
170
|
+
/** 2 to 10 levels, lowest first */
|
|
171
|
+
| { name: string; type: "score"; instructions: string; levels: Level[] }
|
|
172
|
+
|
|
173
|
+
export interface ChoiceOption {
|
|
174
|
+
value: string
|
|
175
|
+
description?: string
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export interface Level {
|
|
179
|
+
label: string
|
|
180
|
+
description?: string
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* an answer in the Decisions API's shape: a predicate gives the probability it holds; a choice
|
|
185
|
+
* its value, a score a 0-based (possibly fractional) level index, each with probabilities and
|
|
186
|
+
* confidence when the judge gives them; a refusal nothing else
|
|
187
|
+
*/
|
|
188
|
+
export type Answer =
|
|
189
|
+
| { type: "predicate"; name: string; probability: number }
|
|
190
|
+
| { type: "choice"; name: string; choice: string; probabilities?: { value: string; probability: number }[]; confidence?: number }
|
|
191
|
+
| { type: "score"; name: string; score: number; probabilities?: { value: number; label: string; probability: number }[]; confidence?: number }
|
|
192
|
+
| { type: "refusal"; name: string }
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* What a translator gets: the paragraphs of the mail (or selection) the user
|
|
196
|
+
* translates, and the target language (BCP 47). source is "" (detect it).
|
|
197
|
+
* The texts may be long: split them as your service requires.
|
|
198
|
+
*/
|
|
199
|
+
export interface TranslateRequest {
|
|
200
|
+
texts: string[]
|
|
201
|
+
source: string
|
|
202
|
+
target: string
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** One translation per request text, in order, and the source language detected (BCP 47). */
|
|
206
|
+
export interface TranslateResult {
|
|
207
|
+
texts: string[]
|
|
208
|
+
source: string
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* A translation channel the user can pick in Settings › General. The plugin
|
|
213
|
+
* must declare "capabilities": ["translate"] in plugin.json and register in
|
|
214
|
+
* its default function. It may fetch from every host in permissions.net
|
|
215
|
+
* without asking each time; the user chose it and clicked Translate.
|
|
216
|
+
*/
|
|
217
|
+
export interface Translator {
|
|
218
|
+
translate(req: TranslateRequest): MaybePromise<TranslateResult>
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export interface Ctx {
|
|
222
|
+
on(event: "message.received", handler: (message: ReceivedMessage, info: DeliveryInfo) => MaybePromise<void>): void
|
|
223
|
+
on(event: "message.beforeSend", handler: (draft: OutgoingDraft) => MaybePromise<SendCheck | void>): void
|
|
224
|
+
|
|
225
|
+
actions: { register(action: Action): void }
|
|
226
|
+
cards: { register(card: CardProvider): void }
|
|
227
|
+
tools: { register(tool: Tool): void }
|
|
228
|
+
/** needs "capabilities": ["translate"]; at most one */
|
|
229
|
+
translators: { register(translator: Translator): void }
|
|
230
|
+
|
|
231
|
+
/** the user's configuration, secrets included; read-only */
|
|
232
|
+
readonly config: Readonly<Record<string, string | number | boolean | undefined>>
|
|
233
|
+
/** needs mail:read; setFlags, move, createDraft and updateDraft need mail:write */
|
|
234
|
+
mail: Mail
|
|
235
|
+
/**
|
|
236
|
+
* needs llm: true. complete runs on the user's default model service. decide runs on
|
|
237
|
+
* the user's judge service, which may be another vendor's (else the default model).
|
|
238
|
+
*/
|
|
239
|
+
llm: {
|
|
240
|
+
complete(prompt: string): Promise<string>
|
|
241
|
+
/** input and all question text at most 64 KB; at most 128 questions; at most 2 calls at once */
|
|
242
|
+
decide(input: string, questions: Question[]): Promise<Answer[]>
|
|
243
|
+
}
|
|
244
|
+
/** https only, to hosts declared in permissions.net */
|
|
245
|
+
net: { fetch(url: string, init?: FetchInit): Promise<FetchResponse> }
|
|
246
|
+
/** this plugin's own key-value store */
|
|
247
|
+
storage: {
|
|
248
|
+
get(key: string): Promise<string | undefined>
|
|
249
|
+
set(key: string, value: string): Promise<void>
|
|
250
|
+
delete(key: string): Promise<void>
|
|
251
|
+
}
|
|
252
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@godwit/sdk",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.6.0",
|
|
4
|
+
"description": "Types for Godwit plugins",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/godwit-email/godwit.git",
|
|
9
|
+
"directory": "sdk"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/godwit-email/godwit/tree/main/sdk",
|
|
12
|
+
"types": "godwit.d.ts",
|
|
13
|
+
"files": [
|
|
14
|
+
"godwit.d.ts"
|
|
15
|
+
],
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
}
|
|
19
|
+
}
|
package/README.md
DELETED