@cerebro-labs/agentnava-sdk 0.26.0 → 0.46.1
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 +212 -23
- package/account.d.ts +154 -0
- package/account.js +219 -0
- package/account.js.map +1 -0
- package/agent.d.ts +229 -87
- package/agent.js +310 -125
- package/agent.js.map +1 -1
- package/apps.generated.d.ts +154 -0
- package/apps.generated.js +152 -0
- package/apps.generated.js.map +1 -0
- package/attach.d.ts +25 -26
- package/attach.js +53 -66
- package/attach.js.map +1 -1
- package/connection.d.ts +79 -82
- package/connection.js +67 -134
- package/connection.js.map +1 -1
- package/conversation.d.ts +55 -35
- package/conversation.js +70 -50
- package/conversation.js.map +1 -1
- package/database.d.ts +53 -0
- package/database.js +69 -0
- package/database.js.map +1 -0
- package/end-user.d.ts +58 -47
- package/end-user.js +62 -72
- package/end-user.js.map +1 -1
- package/errors.d.ts +2 -1
- package/errors.js +2 -1
- package/errors.js.map +1 -1
- package/http.d.ts +5 -0
- package/http.js +109 -8
- package/http.js.map +1 -1
- package/import-tools.d.ts +54 -33
- package/import-tools.js +526 -124
- package/import-tools.js.map +1 -1
- package/index.d.ts +5 -2
- package/index.js +9 -2
- package/index.js.map +1 -1
- package/load-agent-dir.js +28 -5
- package/load-agent-dir.js.map +1 -1
- package/package.json +5 -1
- package/secret.d.ts +1 -1
- package/secret.js +1 -1
- package/secret.js.map +1 -1
- package/templates-inline.js +1 -1
- package/templates-inline.js.map +1 -1
- package/turn.d.ts +1 -1
- package/turn.js +77 -29
- package/turn.js.map +1 -1
- package/types.d.ts +462 -83
- package/types.js.map +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.js.map +1 -1
- package/workflows.d.ts +10 -0
- package/workflows.js +16 -0
- package/workflows.js.map +1 -1
- package/workspace.d.ts +80 -62
- package/workspace.js +92 -75
- package/workspace.js.map +1 -1
- package/connection-status.d.ts +0 -28
- package/connection-status.js +0 -61
- package/connection-status.js.map +0 -1
package/types.d.ts
CHANGED
|
@@ -1,20 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
import type { AppId } from './apps.generated.ts';
|
|
2
|
+
import type { Connection } from './connection.ts';
|
|
3
|
+
/** The quality of model an agent's turns run on, and what each turn costs.
|
|
4
|
+
*
|
|
5
|
+
* `fast` is the one that surprises people: it buys LATENCY rather than
|
|
6
|
+
* capability, runs a smaller model on silicon built for time-to-first-token,
|
|
7
|
+
* and costs MORE than `premium` while being less capable. Pick it for voice
|
|
8
|
+
* and interactive agents, not to save money. `best` is the strongest model. */
|
|
9
|
+
export type Grade = 'standard' | 'premium' | 'fast' | 'best';
|
|
2
10
|
export type Filesystem = 'drive' | 'none';
|
|
3
|
-
/** Where a
|
|
11
|
+
/** Where a SECRET is supplied.
|
|
4
12
|
*
|
|
5
13
|
* 'fixed' is set once on the agent and used by every conversation. 'conversation'
|
|
6
14
|
* is asked for when a conversation starts, so each user brings their own. The
|
|
7
|
-
* two DO NOT substitute for each other:
|
|
8
|
-
*
|
|
9
|
-
export type Scope = 'fixed' | 'conversation';
|
|
10
|
-
/** WHOSE credential a stored account or value is, which is a different question
|
|
11
|
-
* from `Scope` above. `Scope` is what an agent DECLARES it needs; this is who
|
|
12
|
-
* a row that exists actually belongs to.
|
|
15
|
+
* two DO NOT substitute for each other: a value set on the agent does not
|
|
16
|
+
* satisfy a declaration scoped 'conversation'.
|
|
13
17
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
export type
|
|
18
|
+
* Connections stopped using this in 0.44. A connection says WHOSE ACCOUNT it
|
|
19
|
+
* uses instead: the agent creator's (`account`) or each end user's own
|
|
20
|
+
* (`endUser: true`). See `AgentConnection`. */
|
|
21
|
+
export type Scope = 'fixed' | 'conversation';
|
|
18
22
|
export interface WorkspaceInfo {
|
|
19
23
|
id: string;
|
|
20
24
|
name: string;
|
|
@@ -31,37 +35,160 @@ export interface Workflow {
|
|
|
31
35
|
}
|
|
32
36
|
export type Trigger = {
|
|
33
37
|
kind: 'chat';
|
|
34
|
-
} | {
|
|
38
|
+
} | ({
|
|
35
39
|
kind: 'schedule';
|
|
40
|
+
enabled?: boolean;
|
|
36
41
|
cron: string;
|
|
37
42
|
timezone?: string;
|
|
38
43
|
message: string;
|
|
39
|
-
} | {
|
|
44
|
+
} & TriggerTarget) | {
|
|
40
45
|
kind: 'interval';
|
|
41
46
|
seconds: number;
|
|
42
47
|
maxRuns?: number;
|
|
43
48
|
message: string;
|
|
44
|
-
} | {
|
|
49
|
+
} | ({
|
|
45
50
|
kind: 'webhook';
|
|
46
51
|
message?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Where your system POSTs, set by the platform. Read it from the agent
|
|
54
|
+
* that `setTriggers()` returns: `agent.data?.triggers`. Anything you
|
|
55
|
+
* send here is ignored, so passing back a list you read is safe and
|
|
56
|
+
* keeps the same URL. One webhook per agent; `rotateWebhookUrl()`
|
|
57
|
+
* replaces the URL.
|
|
58
|
+
*/
|
|
47
59
|
url?: string;
|
|
48
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Check WHO sent each delivery, beyond knowing the URL. See
|
|
62
|
+
* WebhookVerify for the schemes and an example. Leave it out to keep
|
|
63
|
+
* what the webhook has. The secret is stored encrypted and never read
|
|
64
|
+
* back: a read says `secretSet: true` instead.
|
|
65
|
+
*/
|
|
66
|
+
verify?: WebhookVerify;
|
|
67
|
+
} & TriggerTarget);
|
|
49
68
|
/**
|
|
50
|
-
*
|
|
69
|
+
* How a webhook checks its sender. Platforms that send webhooks sign every
|
|
70
|
+
* delivery with a secret they show you when you add the URL there; give it
|
|
71
|
+
* here, and a delivery whose signature does not match is refused (401) and
|
|
72
|
+
* never runs the agent.
|
|
51
73
|
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
74
|
+
* ```ts
|
|
75
|
+
* { kind: 'webhook', verify: { kind: 'stripe', secret: 'whsec_...' } }
|
|
76
|
+
* { kind: 'webhook', verify: { kind: 'header', header: 'X-Webhook-Secret', secret: '...' } }
|
|
77
|
+
* ```
|
|
56
78
|
*
|
|
57
|
-
* The
|
|
58
|
-
*
|
|
79
|
+
* The schemes: `stripe`, `github`, `shopify`, `slack` and
|
|
80
|
+
* `standard` (the Standard Webhooks spec) check that platform's signature;
|
|
81
|
+
* `header` checks a header your sender adds (Zapier, Make, n8n, your own code
|
|
82
|
+
* can all add one); `none` relies on the URL alone.
|
|
59
83
|
*/
|
|
60
|
-
export
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
84
|
+
export type WebhookVerify = {
|
|
85
|
+
kind: 'none';
|
|
86
|
+
} | {
|
|
87
|
+
kind: 'stripe' | 'github' | 'shopify' | 'slack' | 'standard';
|
|
88
|
+
secret?: string;
|
|
89
|
+
secretSet?: boolean;
|
|
90
|
+
} | {
|
|
91
|
+
kind: 'header';
|
|
92
|
+
header: string;
|
|
93
|
+
secret?: string;
|
|
94
|
+
secretSet?: boolean;
|
|
95
|
+
};
|
|
96
|
+
/** One delivery a webhook received, newest first from `agent.webhookDeliveries()`. */
|
|
97
|
+
export interface WebhookDelivery {
|
|
98
|
+
id: string;
|
|
99
|
+
receivedAt: string;
|
|
100
|
+
/** `pending`: checked and starting. `repeat`: the sender retried a delivery
|
|
101
|
+
* already accepted; the agent did not run again. */
|
|
102
|
+
outcome: 'pending' | 'accepted' | 'refused' | 'repeat' | 'test';
|
|
103
|
+
/** Why it was refused. */
|
|
104
|
+
reason?: string;
|
|
105
|
+
/** The sender's own id for it, when it gave one. */
|
|
106
|
+
deliveryId?: string;
|
|
107
|
+
/** The conversation it ran in. */
|
|
108
|
+
conversationId?: string;
|
|
64
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* WHERE a schedule or webhook runs. Name a conversation, or an end user, or
|
|
112
|
+
* neither; never both.
|
|
113
|
+
*
|
|
114
|
+
* ```ts
|
|
115
|
+
* const conversation = await agent.start({ endUserId: 'ops-app' });
|
|
116
|
+
* await agent.setTriggers([
|
|
117
|
+
* { kind: 'chat' },
|
|
118
|
+
* // Every firing lands in THIS conversation: its history, its drive.
|
|
119
|
+
* { kind: 'schedule', cron: '0 15 * * *', message: 'REFRESH', conversationId: conversation.id },
|
|
120
|
+
* ]);
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
export type TriggerTarget = {
|
|
124
|
+
/**
|
|
125
|
+
* The conversation every firing CONTINUES: it sees that conversation's
|
|
126
|
+
* history and its drive, and its end user comes with it. Each firing
|
|
127
|
+
* also moves the conversation to the agent's latest version, so a fix
|
|
128
|
+
* you publish reaches it.
|
|
129
|
+
*
|
|
130
|
+
* This is the ONLY way a trigger continues one of your conversations.
|
|
131
|
+
* One end user can have many, so naming the end user cannot say which.
|
|
132
|
+
*
|
|
133
|
+
* Must be a conversation of this agent, started for one of your end
|
|
134
|
+
* users (the id `agent.start()` returned). Anything else is refused
|
|
135
|
+
* when you set the trigger. If the conversation is deleted later, the
|
|
136
|
+
* firings fail and say so; none is opened in its place.
|
|
137
|
+
*/
|
|
138
|
+
conversationId: string;
|
|
139
|
+
userId?: undefined;
|
|
140
|
+
} | {
|
|
141
|
+
conversationId?: undefined;
|
|
142
|
+
/**
|
|
143
|
+
* The end user each firing is for, when it names no conversation. Each
|
|
144
|
+
* firing STARTS A NEW CONVERSATION for them, with an empty drive, and it
|
|
145
|
+
* is listed by `agent.conversations({ endUser })`. To keep adding to
|
|
146
|
+
* one conversation instead, name it with `conversationId`.
|
|
147
|
+
*
|
|
148
|
+
* Your id, as in `agent.start({ endUserId })`; the platform's prefixes
|
|
149
|
+
* (`member:`, `visitor:`, `job:`) are refused.
|
|
150
|
+
*
|
|
151
|
+
* Name neither and the trigger keeps one conversation of its own that
|
|
152
|
+
* every firing continues.
|
|
153
|
+
*/
|
|
154
|
+
userId?: string;
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* One connection in an agent's setup, as it reads back: a NAME, an APP, and
|
|
158
|
+
* WHOSE ACCOUNT. Exactly one of these two:
|
|
159
|
+
*
|
|
160
|
+
* | the connection says | whose account | the person signs in |
|
|
161
|
+
* |---|---|---|
|
|
162
|
+
* | `account: '<id>'` | the agent creator's: one account in this workspace, from `ws.accounts.connect()` | once, and every conversation uses it |
|
|
163
|
+
* | `endUser: true` | the end user's: each person talking to the agent | once each, remembered for them |
|
|
164
|
+
*
|
|
165
|
+
* A turn uses EXACTLY the account the setup names, and never another one.
|
|
166
|
+
* There is no fallback to some other account of the same app: an account that
|
|
167
|
+
* is not signed in leaves the connection unavailable, and the agent says so.
|
|
168
|
+
*
|
|
169
|
+
* `name` tells two connections of one app apart, such as `work-gmail` and
|
|
170
|
+
* `personal-gmail`. 1 to 64 characters, lowercase letters, digits and dashes,
|
|
171
|
+
* no dash at either end, unique on the agent. Left out when sent, it is the
|
|
172
|
+
* app's id.
|
|
173
|
+
*
|
|
174
|
+
* Part of the agent's CONFIGURATION, so changing a connection publishes a
|
|
175
|
+
* version. The account itself is not versioned: signing in again reaches every
|
|
176
|
+
* agent that names it. To send one, build it with `Connection.creatorAccount()`
|
|
177
|
+
* or `Connection.endUserAccount()`.
|
|
178
|
+
*/
|
|
179
|
+
export type AgentConnection = {
|
|
180
|
+
name: string;
|
|
181
|
+
/** The app's id: `App.GMAIL` is `'gmail'`. */
|
|
182
|
+
app: AppId;
|
|
183
|
+
/** An account id in this workspace whose app is `app`. */
|
|
184
|
+
account: string;
|
|
185
|
+
endUser?: never;
|
|
186
|
+
} | {
|
|
187
|
+
name: string;
|
|
188
|
+
app: AppId;
|
|
189
|
+
endUser: true;
|
|
190
|
+
account?: never;
|
|
191
|
+
};
|
|
65
192
|
/** What an agent NEEDS, not the stored value. `Secret` is the value. */
|
|
66
193
|
export interface SecretRequirement {
|
|
67
194
|
name: string;
|
|
@@ -83,10 +210,15 @@ export interface McpServer {
|
|
|
83
210
|
timeoutMs?: number;
|
|
84
211
|
}
|
|
85
212
|
export interface HttpToolParam {
|
|
86
|
-
type: 'string' | 'number' | 'boolean';
|
|
213
|
+
type: 'string' | 'number' | 'boolean' | 'object' | 'array';
|
|
87
214
|
description?: string;
|
|
88
215
|
required?: boolean;
|
|
89
|
-
choices?: (string | number)[];
|
|
216
|
+
choices?: (string | number | boolean | null)[];
|
|
217
|
+
nullable?: boolean;
|
|
218
|
+
integer?: boolean;
|
|
219
|
+
properties?: Record<string, HttpToolParam>;
|
|
220
|
+
items?: HttpToolParam;
|
|
221
|
+
additionalProperties?: boolean;
|
|
90
222
|
}
|
|
91
223
|
export interface HttpTool {
|
|
92
224
|
name: string;
|
|
@@ -108,7 +240,8 @@ export interface AgentData {
|
|
|
108
240
|
filesystem: Filesystem;
|
|
109
241
|
tools: string[];
|
|
110
242
|
workflows: Workflow[];
|
|
111
|
-
|
|
243
|
+
/** The apps it uses, each saying whose account. See `AgentConnection`. */
|
|
244
|
+
connections: AgentConnection[];
|
|
112
245
|
secrets: SecretRequirement[];
|
|
113
246
|
parameters: Parameter[];
|
|
114
247
|
triggers: Trigger[];
|
|
@@ -118,59 +251,163 @@ export interface AgentData {
|
|
|
118
251
|
* when none are attached, so a caller never has to distinguish "none" from
|
|
119
252
|
* "an older server that did not send the field". */
|
|
120
253
|
knowledgeBases: string[];
|
|
254
|
+
/** Workspace databases this agent may query, by key. Always present, like
|
|
255
|
+
* `knowledgeBases`. */
|
|
256
|
+
databases: string[];
|
|
121
257
|
version: number;
|
|
122
258
|
createdAt: string;
|
|
123
259
|
updatedAt: string;
|
|
260
|
+
/** Where it is live, as the portal shows it. The API works it out by the
|
|
261
|
+
* same rule it runs the agent by, so `channels.api === 'on'` is exactly
|
|
262
|
+
* "a turn will be taken". Read-only: nothing sets it. Sent by `agent.get()`
|
|
263
|
+
* and `ws.agents.list()`; absent from what create and update return, so
|
|
264
|
+
* call `get()` for it. */
|
|
265
|
+
readonly status?: AgentStatus;
|
|
266
|
+
}
|
|
267
|
+
/** What `agent.websiteChat.turnOn()` gives back: what to put on a website. */
|
|
268
|
+
export interface WebsiteChat {
|
|
269
|
+
/** The hosted chat page. Share it, or open it in an iframe. */
|
|
270
|
+
readonly chatUrl: string;
|
|
271
|
+
/** The publishable token for the embed script. Safe in a public web page:
|
|
272
|
+
* it can only talk to this one agent. Your API key never goes there. */
|
|
273
|
+
readonly publicToken: string;
|
|
274
|
+
/** The id the embed script's `data-agent-id` takes. */
|
|
275
|
+
readonly embedAgentId: string;
|
|
276
|
+
/** The version the website chat serves from now on. */
|
|
277
|
+
readonly versionNumber: number;
|
|
278
|
+
}
|
|
279
|
+
/** Where an agent is live. See `AgentData.status`. */
|
|
280
|
+
export interface AgentStatus {
|
|
281
|
+
/** True when any channel is on. */
|
|
282
|
+
readonly live: boolean;
|
|
283
|
+
/** Paused by its owner: nothing runs it until it is resumed. */
|
|
284
|
+
readonly paused: boolean;
|
|
285
|
+
/** Archived: nothing runs it again. */
|
|
286
|
+
readonly archived: boolean;
|
|
287
|
+
readonly channels: {
|
|
288
|
+
/** 'on' when the API takes new turns for it. */
|
|
289
|
+
readonly api: 'on' | 'off';
|
|
290
|
+
/** 'on' when its website chat page answers visitors. 'unavailable' when it
|
|
291
|
+
* needs what each user brings (`eachUserBrings`), which a visitor cannot. */
|
|
292
|
+
readonly websiteChat: 'on' | 'off' | 'unavailable';
|
|
293
|
+
};
|
|
294
|
+
/** Required accounts and secrets of its own that are not set up yet, on the
|
|
295
|
+
* version a new conversation runs. It still runs: the tools that use them
|
|
296
|
+
* fail until they are set up. Empty when nothing is missing. */
|
|
297
|
+
readonly needs: readonly {
|
|
298
|
+
kind: 'connection' | 'secret';
|
|
299
|
+
name: string;
|
|
300
|
+
}[];
|
|
301
|
+
/** The accounts and secrets each user supplies for themselves. */
|
|
302
|
+
readonly eachUserBrings: readonly {
|
|
303
|
+
kind: 'connection' | 'secret';
|
|
304
|
+
name: string;
|
|
305
|
+
}[];
|
|
124
306
|
}
|
|
125
|
-
/**
|
|
307
|
+
/**
|
|
308
|
+
* One of an agent's connections as it stands right now: the account it names,
|
|
309
|
+
* and whether that account works. What `agent.connections.list()` returns.
|
|
310
|
+
*
|
|
311
|
+
* DECLARED IS NOT CONNECTED, and this is the read that tells them apart. A
|
|
312
|
+
* connection can name an account nobody has finished signing in to, or one that
|
|
313
|
+
* was disconnected since; that is the state a setup checklist has to show, and
|
|
314
|
+
* without this the only way to find it is to start a conversation and watch
|
|
315
|
+
* the agent fail.
|
|
126
316
|
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
317
|
+
* Reshaped in 0.44: it used to be keyed by `provider`, with `declared`,
|
|
318
|
+
* `required`, `scope` and `suppliedBy`. A connection is now keyed by its
|
|
319
|
+
* `name`, and it says whose account it uses instead of where one might come
|
|
320
|
+
* from.
|
|
321
|
+
*/
|
|
130
322
|
export interface ConnectionStatus {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
323
|
+
name: string;
|
|
324
|
+
app: AppId;
|
|
325
|
+
/** The agent creator's account the connection names, read fresh. Absent on
|
|
326
|
+
* an end user's connection, and on one whose account is gone. */
|
|
327
|
+
account?: AccountData;
|
|
328
|
+
/** True when each person talking to the agent signs in with their own. */
|
|
329
|
+
endUser?: true;
|
|
330
|
+
/** Whether the connection works now, as the API reports it. For an agent
|
|
331
|
+
* creator's account it follows that account's status. */
|
|
332
|
+
status: string;
|
|
333
|
+
/** Only in the agent's unpublished draft, so no conversation uses it yet. */
|
|
334
|
+
inDraft: boolean;
|
|
335
|
+
/** Removed in the agent's unpublished draft, and still used until the draft
|
|
336
|
+
* is published. */
|
|
337
|
+
removedInDraft: boolean;
|
|
338
|
+
}
|
|
339
|
+
/** Where one account's sign-in stands.
|
|
340
|
+
*
|
|
341
|
+
* 'pending' made, and nobody has finished signing in yet
|
|
342
|
+
* 'connected' signed in and working
|
|
343
|
+
* 'needs_sign_in' it worked, and the app now wants the person to sign in again
|
|
344
|
+
* 'error' the app refused it for another reason
|
|
345
|
+
*/
|
|
346
|
+
export type AccountStatus = 'pending' | 'connected' | 'needs_sign_in' | 'error';
|
|
347
|
+
/** An agent whose setup names an account, and the connection that names it.
|
|
348
|
+
* Counted from the agent's latest published version and its draft, never
|
|
349
|
+
* from older versions. */
|
|
350
|
+
export interface UsedBy {
|
|
351
|
+
/** The agent's id: the same value as `Agent.id`, so compare this one. */
|
|
352
|
+
id: string;
|
|
353
|
+
/** AgentNava's internal handle for the same agent (`agt_...`), not `Agent.id`. */
|
|
354
|
+
agentId: string;
|
|
355
|
+
agentName: string;
|
|
356
|
+
connectionName: string;
|
|
357
|
+
/** Named in the agent's unpublished draft. */
|
|
358
|
+
inDraft: boolean;
|
|
359
|
+
/** Named in the agent's latest published version. */
|
|
360
|
+
published: boolean;
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* One saved sign-in to one app.
|
|
364
|
+
*
|
|
365
|
+
* TWO OWNERS, and the difference is who signs in:
|
|
366
|
+
*
|
|
367
|
+
* | `owner` | whose | a connection uses it as |
|
|
368
|
+
* |---|---|---|
|
|
369
|
+
* | `'workspace'` | the agent creator's, signed in once, usable by any agent | `Connection.creatorAccount(app, account)` |
|
|
370
|
+
* | `'end-user'` | one of YOUR end users', remembered for that person | `Connection.endUserAccount(app)`, in that person's conversations |
|
|
371
|
+
*
|
|
372
|
+
* Both owners are read and changed through the same routes and the same
|
|
373
|
+
* `Account` handle; `owner` says which this is.
|
|
374
|
+
*
|
|
375
|
+
* Nobody handles a token: the person signs in on the app's own page, and this
|
|
376
|
+
* record says who they signed in as, never how.
|
|
377
|
+
*/
|
|
378
|
+
export interface AccountData {
|
|
379
|
+
id: string;
|
|
380
|
+
/** The app's id: `App.GMAIL` is `'gmail'`. */
|
|
381
|
+
app: AppId;
|
|
382
|
+
/** Who it is signed in as: the email or username the app reports. Null until
|
|
383
|
+
* somebody has finished signing in. */
|
|
384
|
+
label: string | null;
|
|
385
|
+
/** Your own name for it, such as `'Support inbox'`. Null when none was given. */
|
|
386
|
+
nickname: string | null;
|
|
387
|
+
status: AccountStatus;
|
|
388
|
+
/** True while a reconnect waits for the person to sign in again. The
|
|
389
|
+
* account keeps working meanwhile, so `status` can still say
|
|
390
|
+
* `'connected'`; `waitUntilConnected()` waits for this to clear. */
|
|
391
|
+
reconnecting: boolean;
|
|
392
|
+
owner: 'workspace' | 'end-user';
|
|
393
|
+
/** The end user it belongs to, when `owner` is `'end-user'`. An id from YOUR
|
|
394
|
+
* database, never a workspace member's. */
|
|
395
|
+
endUserId?: string;
|
|
396
|
+
connectedAt: string | null;
|
|
397
|
+
lastCheckedAt: string | null;
|
|
398
|
+
/** The agents whose setup names this account. Empty for an end user's
|
|
399
|
+
* account, which a setup never names by id. */
|
|
400
|
+
usedBy: UsedBy[];
|
|
401
|
+
}
|
|
402
|
+
/** An end user's account a conversation still needs, with the link that
|
|
403
|
+
* person signs in at. From `conversation.accountsNeeded()`. */
|
|
404
|
+
export interface AccountNeeded {
|
|
405
|
+
/** The connection's name on the agent. */
|
|
406
|
+
name: string;
|
|
407
|
+
app: AppId;
|
|
408
|
+
/** Send the person here. They sign in once, and every later conversation
|
|
409
|
+
* of theirs has it. */
|
|
410
|
+
url: string;
|
|
174
411
|
}
|
|
175
412
|
/** Something a conversation is still missing before it can work. */
|
|
176
413
|
export interface Requirement {
|
|
@@ -181,6 +418,9 @@ export interface Requirement {
|
|
|
181
418
|
export interface AgentConversationData {
|
|
182
419
|
id: string;
|
|
183
420
|
agentId: string;
|
|
421
|
+
/** The number of the agent version this conversation runs, as `agent.version`
|
|
422
|
+
* numbers them. Fixed at start, except that a schedule or webhook naming the
|
|
423
|
+
* conversation moves it to the latest version at each firing. */
|
|
184
424
|
version: number;
|
|
185
425
|
startedAt: string;
|
|
186
426
|
title?: string;
|
|
@@ -351,9 +591,44 @@ export interface AgentFields {
|
|
|
351
591
|
* that was valid stays valid.
|
|
352
592
|
*/
|
|
353
593
|
knowledgeBases?: string[];
|
|
594
|
+
/**
|
|
595
|
+
* Workspace databases this agent may query, by key.
|
|
596
|
+
*
|
|
597
|
+
* Register the database first with `ws.databases.create()`, which logs in
|
|
598
|
+
* and gives it the key; then name the key here. Naming it is the grant: a
|
|
599
|
+
* database answers only the agents whose configuration names it, and the
|
|
600
|
+
* agent's prompt lists them so it knows what to query.
|
|
601
|
+
*
|
|
602
|
+
* Part of the CONFIGURATION, so changing it publishes a version. A key that
|
|
603
|
+
* names no database is refused when the configuration is saved, and
|
|
604
|
+
* removing a database is refused while any agent names it.
|
|
605
|
+
*/
|
|
606
|
+
databases?: string[];
|
|
354
607
|
tools?: string[];
|
|
355
608
|
workflows?: Workflow[];
|
|
356
|
-
|
|
609
|
+
/**
|
|
610
|
+
* The apps this agent uses, each a NAMED connection that says whose account
|
|
611
|
+
* it uses: the agent creator's account, or each end user's own. See
|
|
612
|
+
* `Connection` and `AgentConnection`.
|
|
613
|
+
*
|
|
614
|
+
* ```ts
|
|
615
|
+
* connections: [
|
|
616
|
+
* Connection.creatorAccount(App.GMAIL, work, { name: 'work-gmail' }),
|
|
617
|
+
* Connection.creatorAccount(App.GMAIL, personal, { name: 'personal-gmail' }),
|
|
618
|
+
* Connection.endUserAccount(App.GOOGLE_CALENDAR),
|
|
619
|
+
* ]
|
|
620
|
+
* ```
|
|
621
|
+
*
|
|
622
|
+
* The builders make plain objects, `{ app, account: '<id>' }` and
|
|
623
|
+
* `{ app, endUser: true }`, and those objects are accepted as they are.
|
|
624
|
+
* `App.GMAIL` is the string `'gmail'`, so a plain app id works too.
|
|
625
|
+
*
|
|
626
|
+
* Part of the CONFIGURATION, like `databases`, so changing it publishes a
|
|
627
|
+
* version. An unknown account id, an account of a different app, a repeated
|
|
628
|
+
* name or a name of the wrong shape is refused when the configuration is
|
|
629
|
+
* saved, naming the problem.
|
|
630
|
+
*/
|
|
631
|
+
connections?: Connection[];
|
|
357
632
|
secrets?: SecretRequirement[];
|
|
358
633
|
parameters?: Parameter[];
|
|
359
634
|
triggers?: Trigger[];
|
|
@@ -367,13 +642,15 @@ export interface ProjectFields {
|
|
|
367
642
|
grade?: Grade;
|
|
368
643
|
agents?: string[];
|
|
369
644
|
}
|
|
370
|
-
/**
|
|
371
|
-
*
|
|
645
|
+
/** Secret VALUES supplied to an agent (`agent.attach`) or to one conversation
|
|
646
|
+
* (`conversation.attach`): the secrets its agent declared.
|
|
647
|
+
*
|
|
648
|
+
* Accounts are no longer supplied this way (0.44). An agent's setup names the
|
|
649
|
+
* account each connection uses, so there is nothing left to attach. */
|
|
372
650
|
export interface Bindings {
|
|
373
651
|
secrets?: Record<string, string>;
|
|
374
|
-
connections?: Record<string, string>;
|
|
375
652
|
}
|
|
376
|
-
/** One markdown file read off disk: a workflow
|
|
653
|
+
/** One markdown file read off disk: a workflow or a subagent.
|
|
377
654
|
*
|
|
378
655
|
* `when` is OPTIONAL here and required at publish. A file on disk has no `when`
|
|
379
656
|
* until someone writes one, and refusing to read it would be the wrong place to
|
|
@@ -389,7 +666,6 @@ export interface SpecFile {
|
|
|
389
666
|
export interface SpecInput extends Omit<AgentFields, 'workflows'> {
|
|
390
667
|
key: string;
|
|
391
668
|
workflows?: SpecFile[];
|
|
392
|
-
skills?: SpecFile[];
|
|
393
669
|
subagents?: SpecFile[];
|
|
394
670
|
widgets?: {
|
|
395
671
|
name: string;
|
|
@@ -483,3 +759,106 @@ export interface SecretMeta {
|
|
|
483
759
|
updatedAt?: string;
|
|
484
760
|
lastUsedAt?: string | null;
|
|
485
761
|
}
|
|
762
|
+
/** A SQL engine AgentNava can query. */
|
|
763
|
+
export type DatabaseEngine = 'postgres' | 'mysql' | 'sqlserver';
|
|
764
|
+
/** How the connection to a database is encrypted. `verify` (the default)
|
|
765
|
+
* encrypts and always checks the server's certificate: against public and
|
|
766
|
+
* cloud CAs and the host name, or, for a database with its own home-made CA,
|
|
767
|
+
* against the CA AgentNava trusted the first time it connected. `disable` is
|
|
768
|
+
* for a server with no SSL at all. */
|
|
769
|
+
export type DatabaseTls = 'verify' | 'disable';
|
|
770
|
+
/**
|
|
771
|
+
* How to log in to a database: a connection string, OR the same login as
|
|
772
|
+
* separate fields. Never both; a request with both is refused.
|
|
773
|
+
*
|
|
774
|
+
* Read-only unless `writable: true`, which no SQL the agent sends can override.
|
|
775
|
+
*/
|
|
776
|
+
export type DatabaseLogin = {
|
|
777
|
+
/** `postgres://`, `postgresql://` or `mysql://`, with the user (and the
|
|
778
|
+
* password, when there is one) in it. An `sslmode` in the string sets `tls`. */
|
|
779
|
+
url: string;
|
|
780
|
+
engine?: DatabaseEngine;
|
|
781
|
+
/** Overrides the string's `sslmode`. */
|
|
782
|
+
tls?: DatabaseTls;
|
|
783
|
+
writable?: boolean;
|
|
784
|
+
} | {
|
|
785
|
+
engine: DatabaseEngine;
|
|
786
|
+
host: string;
|
|
787
|
+
port: number;
|
|
788
|
+
database: string;
|
|
789
|
+
username: string;
|
|
790
|
+
/** Leave it out for a database that takes a user name alone. */
|
|
791
|
+
password?: string;
|
|
792
|
+
tls?: DatabaseTls;
|
|
793
|
+
writable?: boolean;
|
|
794
|
+
};
|
|
795
|
+
/** What `ws.databases.create()` takes: the key agents will name it by, an
|
|
796
|
+
* optional label, and a login. */
|
|
797
|
+
export type DatabaseFields = DatabaseLogin & {
|
|
798
|
+
/** Lowercase letters, digits and dashes, like `shop` or `sales-db`. What an
|
|
799
|
+
* agent configuration stores, so it is not editable afterwards. */
|
|
800
|
+
key: string;
|
|
801
|
+
/** A label for people. Defaults to the key. */
|
|
802
|
+
name?: string;
|
|
803
|
+
};
|
|
804
|
+
/** A registered database as AgentNava reports it: where it is, never how to
|
|
805
|
+
* log in. Neither the password nor the connection string is ever returned. */
|
|
806
|
+
export interface DatabaseData {
|
|
807
|
+
key: string;
|
|
808
|
+
/** The underlying connection's id. */
|
|
809
|
+
id: string;
|
|
810
|
+
name: string;
|
|
811
|
+
engine: DatabaseEngine | null;
|
|
812
|
+
host: string | null;
|
|
813
|
+
port: number | null;
|
|
814
|
+
database: string | null;
|
|
815
|
+
tls: DatabaseTls | null;
|
|
816
|
+
writable: boolean;
|
|
817
|
+
status: string;
|
|
818
|
+
createdAt: string;
|
|
819
|
+
/** The agents whose configuration names this database. */
|
|
820
|
+
usedBy: DatabaseUsedBy[];
|
|
821
|
+
}
|
|
822
|
+
/** An agent whose configuration names a database: in its latest published
|
|
823
|
+
* version, in its draft, or in both. */
|
|
824
|
+
export interface DatabaseUsedBy {
|
|
825
|
+
/** The agent's id: the same value as `Agent.id`, so compare this one. */
|
|
826
|
+
id: string;
|
|
827
|
+
/** AgentNava's internal handle for the same agent (`agt_...`), not `Agent.id`. */
|
|
828
|
+
agentId: string;
|
|
829
|
+
/** The agent's display name. */
|
|
830
|
+
name: string;
|
|
831
|
+
/** Named in the agent's latest published version, so its conversations can
|
|
832
|
+
* query the database now. */
|
|
833
|
+
published: boolean;
|
|
834
|
+
/** Named in the configuration being edited: the draft when there is one,
|
|
835
|
+
* else the published version itself. */
|
|
836
|
+
draft: boolean;
|
|
837
|
+
}
|
|
838
|
+
/** One table or view in a database. */
|
|
839
|
+
export interface DatabaseTable {
|
|
840
|
+
schema: string;
|
|
841
|
+
name: string;
|
|
842
|
+
kind: 'table' | 'view';
|
|
843
|
+
}
|
|
844
|
+
/** One column of a table. */
|
|
845
|
+
export interface DatabaseColumn {
|
|
846
|
+
name: string;
|
|
847
|
+
dataType: string;
|
|
848
|
+
nullable: boolean;
|
|
849
|
+
isPrimaryKey: boolean;
|
|
850
|
+
}
|
|
851
|
+
/** What `ws.databases.test()` reports. A refused login is an answer, not an
|
|
852
|
+
* exception, because it is the answer the call exists to get. */
|
|
853
|
+
export type DatabaseTestResult = {
|
|
854
|
+
ok: true;
|
|
855
|
+
engine: DatabaseEngine;
|
|
856
|
+
tableCount: number;
|
|
857
|
+
tables: DatabaseTable[];
|
|
858
|
+
} | {
|
|
859
|
+
ok: false;
|
|
860
|
+
error: {
|
|
861
|
+
code: string;
|
|
862
|
+
message: string;
|
|
863
|
+
};
|
|
864
|
+
};
|