@project-ajax/create 0.0.25 → 0.0.27
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/package.json +1 -1
- package/template/.examples/automation-example.ts +5 -2
- package/template/.examples/oauth-example.ts +44 -13
- package/template/.examples/sync-example.ts +6 -3
- package/template/.examples/tool-example.ts +6 -3
- package/template/AGENTS.md +104 -0
- package/template/README.md +145 -394
- package/template/src/index.ts +7 -4
package/package.json
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { Client } from "@notionhq/client";
|
|
2
|
-
import {
|
|
2
|
+
import { Worker } from "@project-ajax/sdk";
|
|
3
|
+
|
|
4
|
+
const worker = new Worker();
|
|
5
|
+
export default worker;
|
|
3
6
|
|
|
4
7
|
// Initialize the Notion client with OAuth token from environment
|
|
5
8
|
const notion = new Client({
|
|
@@ -19,7 +22,7 @@ type RichTextProperty = {
|
|
|
19
22
|
* 2. Processes it (calls an API, performs logic, etc.)
|
|
20
23
|
* 3. Updates the page with the answer
|
|
21
24
|
*/
|
|
22
|
-
|
|
25
|
+
worker.automation("questionAnswerAutomation", {
|
|
23
26
|
title: "Question Answer Automation",
|
|
24
27
|
description:
|
|
25
28
|
"Reads questions from database pages and updates them with answers",
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Worker } from "@project-ajax/sdk";
|
|
2
|
+
|
|
3
|
+
const worker = new Worker();
|
|
4
|
+
export default worker;
|
|
2
5
|
|
|
3
6
|
/**
|
|
4
7
|
* OAuth capabilities let your worker access third-party APIs.
|
|
@@ -7,38 +10,66 @@ import { oauth } from "@project-ajax/sdk";
|
|
|
7
10
|
*
|
|
8
11
|
* npx workers oauth start <capabilityKey>
|
|
9
12
|
*
|
|
10
|
-
* Where `capabilityKey` is the OAuth capability
|
|
13
|
+
* Where `capabilityKey` is the OAuth capability's key (see `npx workers capabilities list`).
|
|
11
14
|
* Once OAuth completes, the worker runtime exposes the access token via an
|
|
12
15
|
* environment variable and `accessToken()` reads it for you.
|
|
13
16
|
*/
|
|
14
17
|
|
|
15
18
|
// Option 1: Notion-managed provider (recommended when available).
|
|
16
19
|
// Notion owns the OAuth app credentials and the backend has pre-configured provider settings.
|
|
17
|
-
|
|
20
|
+
const googleAuth = worker.oauth("googleAuth", {
|
|
18
21
|
name: "google-calendar",
|
|
19
22
|
provider: "google",
|
|
20
23
|
});
|
|
21
24
|
|
|
22
25
|
// Option 2: User-managed provider (you own the OAuth app credentials).
|
|
23
26
|
// Keep client credentials in worker secrets and read them from `process.env`.
|
|
24
|
-
|
|
27
|
+
const myCustomAuth = worker.oauth("myCustomAuth", {
|
|
25
28
|
name: "my-custom-provider",
|
|
26
29
|
authorizationEndpoint: "https://provider.example.com/oauth/authorize",
|
|
27
30
|
tokenEndpoint: "https://provider.example.com/oauth/token",
|
|
28
31
|
scope: "read write",
|
|
29
|
-
clientId:
|
|
30
|
-
clientSecret:
|
|
32
|
+
clientId: "1234567890",
|
|
33
|
+
clientSecret: process.env.MY_CUSTOM_OAUTH_CLIENT_SECRET ?? "",
|
|
31
34
|
authorizationParams: {
|
|
32
35
|
access_type: "offline",
|
|
33
36
|
prompt: "consent",
|
|
34
37
|
},
|
|
35
38
|
});
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
// Use the OAuth handles in your capabilities
|
|
41
|
+
worker.sync("googleCalendarSync", {
|
|
42
|
+
primaryKeyProperty: "eventId",
|
|
43
|
+
schema: {
|
|
44
|
+
defaultName: "Calendar Events",
|
|
45
|
+
properties: {
|
|
46
|
+
eventId: { type: "text" },
|
|
47
|
+
title: { type: "title" },
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
execute: async () => {
|
|
51
|
+
// Get the OAuth access token
|
|
52
|
+
const token = await googleAuth.accessToken();
|
|
53
|
+
|
|
54
|
+
// Use token to fetch from Google Calendar API
|
|
55
|
+
console.log("Using Google token:", `${token.slice(0, 10)}...`);
|
|
42
56
|
|
|
43
|
-
|
|
44
|
-
}
|
|
57
|
+
return { objects: [], done: true };
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
worker.tool("customApiTool", {
|
|
62
|
+
title: "Custom API Tool",
|
|
63
|
+
description: "Calls a custom API using OAuth",
|
|
64
|
+
schema: {
|
|
65
|
+
type: "object",
|
|
66
|
+
properties: {},
|
|
67
|
+
required: [],
|
|
68
|
+
additionalProperties: false,
|
|
69
|
+
},
|
|
70
|
+
execute: async () => {
|
|
71
|
+
const token = await myCustomAuth.accessToken();
|
|
72
|
+
console.log("Using custom provider token:", `${token.slice(0, 10)}...`);
|
|
73
|
+
return { success: true };
|
|
74
|
+
},
|
|
75
|
+
});
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
+
import { Worker } from "@project-ajax/sdk";
|
|
1
2
|
import * as Builder from "@project-ajax/sdk/builder";
|
|
2
3
|
import * as Schema from "@project-ajax/sdk/schema";
|
|
3
|
-
import { sync } from "@project-ajax/sdk/sync";
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
const worker = new Worker();
|
|
6
|
+
export default worker;
|
|
7
|
+
|
|
8
|
+
worker.sync("mySync", {
|
|
6
9
|
// Which field to use in each object as the primary key. Must be unique.
|
|
7
10
|
primaryKeyProperty: "ID",
|
|
8
11
|
// The schema of the collection to create in Notion.
|
|
9
12
|
schema: {
|
|
10
13
|
// Name of the collection to create in Notion.
|
|
11
|
-
|
|
14
|
+
defaultName: "My Data",
|
|
12
15
|
properties: {
|
|
13
16
|
// See `Schema` for the full list of possible column types.
|
|
14
17
|
Title: Schema.title(),
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Worker } from "@project-ajax/sdk";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const worker = new Worker();
|
|
4
|
+
export default worker;
|
|
5
|
+
|
|
6
|
+
worker.tool<
|
|
4
7
|
{ query?: string | null; limit?: number | null },
|
|
5
8
|
{ results: string[] }
|
|
6
|
-
>({
|
|
9
|
+
>("myTool", {
|
|
7
10
|
title: "My Tool",
|
|
8
11
|
// Description of what this tool does - shown to the AI agent
|
|
9
12
|
description: "Search for items by keyword or ID",
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Repository Guidelines
|
|
2
|
+
|
|
3
|
+
## Project Structure & Module Organization
|
|
4
|
+
- `src/index.ts` defines the worker and capabilities.
|
|
5
|
+
- `.examples/` has focused samples (sync, tool, automation, OAuth).
|
|
6
|
+
- Generated: `dist/` build output, `workers.json` CLI config.
|
|
7
|
+
|
|
8
|
+
## Worker & Capability API (SDK)
|
|
9
|
+
- `@project-ajax/sdk` provides `Worker`, schema helpers, and builders; `@project-ajax/cli` powers `npx workers ...`.
|
|
10
|
+
- Capability keys are unique strings used by the CLI (e.g., `npx workers exec tasksSync`).
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { Worker } from "@project-ajax/sdk";
|
|
14
|
+
import * as Builder from "@project-ajax/sdk/builder";
|
|
15
|
+
import * as Schema from "@project-ajax/sdk/schema";
|
|
16
|
+
|
|
17
|
+
const worker = new Worker();
|
|
18
|
+
export default worker;
|
|
19
|
+
|
|
20
|
+
worker.sync("tasksSync", {
|
|
21
|
+
primaryKeyProperty: "ID",
|
|
22
|
+
schema: { defaultName: "Tasks", properties: { Name: Schema.title(), ID: Schema.richText() } },
|
|
23
|
+
execute: async (context?: { cursor?: string }) => {
|
|
24
|
+
const pageSize = 100;
|
|
25
|
+
const { items, nextCursor } = await fetchItems({ cursor: context?.cursor, limit: pageSize });
|
|
26
|
+
return {
|
|
27
|
+
objects: items.map((item) => ({
|
|
28
|
+
key: item.id,
|
|
29
|
+
properties: { Name: Builder.title(item.name), ID: Builder.richText(item.id) },
|
|
30
|
+
})),
|
|
31
|
+
done: !nextCursor,
|
|
32
|
+
nextContext: nextCursor ? { cursor: nextCursor } : undefined,
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
worker.tool("sayHello", {
|
|
38
|
+
title: "Say Hello",
|
|
39
|
+
description: "Return a greeting",
|
|
40
|
+
schema: { type: "object", properties: { name: { type: "string" } }, required: ["name"], additionalProperties: false },
|
|
41
|
+
execute: ({ name }) => `Hello, ${name}`,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
worker.automation("sendWelcomeEmail", {
|
|
45
|
+
title: "Send Welcome Email",
|
|
46
|
+
description: "Runs from a database automation",
|
|
47
|
+
execute: async () => {},
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
worker.oauth("googleAuth", { name: "my-google-auth", provider: "google" });
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- For user-managed OAuth, supply `name`, `authorizationEndpoint`, `tokenEndpoint`, `clientId`, `clientSecret`, and `scope` (optional: `authorizationParams`, `callbackUrl`, `accessTokenExpireMs`).
|
|
54
|
+
|
|
55
|
+
### Sync Pagination
|
|
56
|
+
|
|
57
|
+
Implement pagination in syncs to avoid exceeding maximum output size limits. Returning too many objects in a single execution can cause the output JSON to exceed size limits and fail.
|
|
58
|
+
|
|
59
|
+
**How pagination works:**
|
|
60
|
+
1. Return a batch of objects with `done: false` and a `nextContext` value
|
|
61
|
+
2. The runtime calls `execute` again with that context
|
|
62
|
+
3. Continue until you return `done: true`
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
worker.sync("paginatedSync", {
|
|
66
|
+
primaryKeyProperty: "ID",
|
|
67
|
+
schema: { defaultName: "Records", properties: { Name: Schema.title(), ID: Schema.richText() } },
|
|
68
|
+
execute: async (context?: { page: number }) => {
|
|
69
|
+
const page = context?.page ?? 1;
|
|
70
|
+
const pageSize = 100;
|
|
71
|
+
const { items, hasMore } = await fetchPage(page, pageSize);
|
|
72
|
+
return {
|
|
73
|
+
objects: items.map((item) => ({
|
|
74
|
+
key: item.id,
|
|
75
|
+
properties: { Name: Builder.title(item.name), ID: Builder.richText(item.id) },
|
|
76
|
+
})),
|
|
77
|
+
done: !hasMore,
|
|
78
|
+
nextContext: hasMore ? { page: page + 1 } : undefined,
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Context types:** The `nextContext` can be any serializable value—a cursor string, page number, timestamp, or complex object. Type your execute function's context parameter to match.
|
|
85
|
+
|
|
86
|
+
## Build, Test, and Development Commands
|
|
87
|
+
- Node >= 22 and npm >= 10.9.2 (see `package.json` engines).
|
|
88
|
+
- `npm run dev`: run `src/index.ts` with live reload.
|
|
89
|
+
- `npm run build`: compile TypeScript to `dist/`.
|
|
90
|
+
- `npm run check`: type-check only (no emit).
|
|
91
|
+
- `npx workers auth login [--env=dev]`: connect to a Notion workspace.
|
|
92
|
+
- `npx workers deploy`: build and publish capabilities.
|
|
93
|
+
- `npx workers exec <capability>`: run a sync or tool.
|
|
94
|
+
|
|
95
|
+
## Coding Style & Naming Conventions
|
|
96
|
+
- TypeScript with `strict` enabled; keep types explicit when shaping I/O.
|
|
97
|
+
- Use tabs for indentation; capability keys in lowerCamelCase.
|
|
98
|
+
|
|
99
|
+
## Testing Guidelines
|
|
100
|
+
- No test runner configured; validate with `npm run check` and a deploy/exec loop.
|
|
101
|
+
|
|
102
|
+
## Commit & Pull Request Guidelines
|
|
103
|
+
- Messages typically use `feat(scope): ...`, `TASK-123: ...`, or version bumps.
|
|
104
|
+
- PRs should describe changes, list commands run, and update examples if behavior changes.
|
package/template/README.md
CHANGED
|
@@ -1,510 +1,261 @@
|
|
|
1
|
-
# Notion
|
|
1
|
+
# Notion Worker
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
A worker is a small Node/TypeScript program hosted by Notion
|
|
4
|
+
that registers capabilities (third-party data syncs, custom agent tools, custom
|
|
5
|
+
automations) to extend Notion. The worker lives in `src/index.ts` and exports a
|
|
6
|
+
single `Worker` instance.
|
|
6
7
|
|
|
7
8
|
## Prerequisites
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
You need Node >= 22, npm >= 10 installed. (The repo will warn you if you don't.)
|
|
10
|
+
- Node >= 22
|
|
11
|
+
- npm >= 10
|
|
12
12
|
|
|
13
13
|
## Quickstart
|
|
14
14
|
|
|
15
|
-
In this Quickstart, you’ll:
|
|
16
|
-
|
|
17
|
-
- Create a new project using this template
|
|
18
|
-
- Publish the example worker to your Notion workspace
|
|
19
|
-
|
|
20
|
-
### 1. Create worker project from template
|
|
21
|
-
|
|
22
|
-
Use `npm init` to setup a project template:
|
|
23
|
-
|
|
24
15
|
```shell
|
|
25
16
|
npm init @project-ajax
|
|
17
|
+
# choose a folder, then:
|
|
18
|
+
cd my-worker
|
|
19
|
+
npm install
|
|
26
20
|
```
|
|
27
21
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
### 2. Install packages and connect the repo to Notion
|
|
31
|
-
|
|
32
|
-
Install packages:
|
|
22
|
+
Connect to a Notion workspace and deploy the sample worker:
|
|
33
23
|
|
|
34
24
|
```shell
|
|
35
|
-
# or whatever you chose for the pathname
|
|
36
|
-
cd my-worker && npm i
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Now, connect the repo to Notion to publish the example worker to your Notion
|
|
40
|
-
workspace:
|
|
41
|
-
|
|
42
|
-
```shell
|
|
43
|
-
# Connect to Notion Prod
|
|
44
25
|
npx workers auth login
|
|
45
|
-
#
|
|
26
|
+
# or target a specific environment:
|
|
46
27
|
npx workers auth login --env=dev
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
This command will open a new page with a command that includes a token. Run that
|
|
50
|
-
command locally. It will look like this:
|
|
51
|
-
|
|
52
|
-
```shell
|
|
53
|
-
# example
|
|
54
|
-
npx workers auth login v1.user.wAFygwEZ-[...] --env=dev
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### 3. Deploy
|
|
58
|
-
|
|
59
|
-
Run the following command to deploy this repo's example workers to your Notion
|
|
60
|
-
workspace:
|
|
61
|
-
|
|
62
|
-
```shell
|
|
63
28
|
npx workers deploy
|
|
64
|
-
|
|
65
|
-
Deploying worker...
|
|
66
|
-
Updating worker...
|
|
67
|
-
Building worker bundle...
|
|
68
|
-
Uploading bundle...
|
|
69
|
-
Fetching and saving worker capabilities...
|
|
70
|
-
✓ Successfully deployed worker
|
|
71
29
|
```
|
|
72
30
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
The sample worker installs three capabilities:
|
|
76
|
-
|
|
77
|
-
- [Synced database](#try-the-synced-database)
|
|
78
|
-
- [Agent tool](#try-the-agent-tool)
|
|
79
|
-
- [Automation](#try-the-automation)
|
|
80
|
-
|
|
81
|
-
#### Try the synced database
|
|
82
|
-
|
|
83
|
-
After deploying, the sync runs automatically and creates a database in your
|
|
84
|
-
private pages - you can find it in your sidebar or by searching "Sample Tasks".
|
|
85
|
-
|
|
86
|
-
Alternatively, run the sync via the CLI to get the URL:
|
|
31
|
+
Run the sample sync to create a database:
|
|
87
32
|
|
|
88
33
|
```shell
|
|
89
34
|
npx workers exec tasksSync
|
|
90
35
|
```
|
|
91
36
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
#### Try the agent tool
|
|
95
|
-
|
|
96
|
-
To exercise the sample agent tool, first navigate to a new or existing custom
|
|
97
|
-
agent in Notion.
|
|
98
|
-
|
|
99
|
-
On the settings tab, choose Add connection:
|
|
100
|
-
|
|
101
|
-
<img src="./docs/custom-agent-add-connection.png" style="width:400px">
|
|
102
|
-
|
|
103
|
-
Scroll down to find the installed worker which has the name used when you
|
|
104
|
-
deployed the worker. Click Add.
|
|
105
|
-
|
|
106
|
-
<img src="./docs/custom-agent-select-worker.png" style="width:400px">
|
|
107
|
-
|
|
108
|
-
Save settings, then navigate to the **chat** tab. Our sample tool call allows
|
|
109
|
-
for searching tasks by id or keyword - try asking Agent to find tasks related to
|
|
110
|
-
"Ajax" or "worker".
|
|
111
|
-
|
|
112
|
-
#### Try the automation
|
|
37
|
+
## Glossary
|
|
113
38
|
|
|
114
|
-
|
|
39
|
+
- Worker: The Node/TypeScript program you deploy, defined in `src/index.ts`.
|
|
40
|
+
- Capability: A named sync, tool, automation, or OAuth definition registered on a worker.
|
|
41
|
+
- Secret: A key/value stored with `npx workers secrets`, exposed as environment variables (for example, `process.env.SECRET_NAME`).
|
|
115
42
|
|
|
116
|
-
|
|
43
|
+
## Build a Worker
|
|
117
44
|
|
|
118
|
-
|
|
45
|
+
Create the worker instance and export it. Register capabilities on the same
|
|
46
|
+
instance:
|
|
119
47
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
2. Select your worker
|
|
123
|
-
3. In `Recent runs` click `automation:completeTaskAutomation`
|
|
48
|
+
```ts
|
|
49
|
+
import { Worker } from "@project-ajax/sdk";
|
|
124
50
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
Begin by using `npm init @project-ajax`, and then customize `index.ts` with
|
|
128
|
-
capabilities you'd like to include in your worker.
|
|
129
|
-
|
|
130
|
-
### Writing a sync function
|
|
131
|
-
|
|
132
|
-
[Sync functions](#sync) populate Notion collections with data from external
|
|
133
|
-
sources.
|
|
134
|
-
|
|
135
|
-
See the [sync example](./.examples/sync-example.ts) for a complete example.
|
|
136
|
-
|
|
137
|
-
### Writing a tool for custom agents
|
|
138
|
-
|
|
139
|
-
[Tools](#tools) provide custom actions that can be invoked by custom agents in
|
|
140
|
-
your Notion workspace.
|
|
141
|
-
|
|
142
|
-
See the [tool example](./.examples/tool-example.ts) for a complete example.
|
|
143
|
-
|
|
144
|
-
### Writing an automation
|
|
145
|
-
|
|
146
|
-
[Automations](#automations) provide custom actions that can be triggered from
|
|
147
|
-
database automations in your Notion workspace.
|
|
148
|
-
|
|
149
|
-
See the [automation example](./.examples/automation-example.ts) for a complete example.
|
|
150
|
-
|
|
151
|
-
## Secrets
|
|
152
|
-
|
|
153
|
-
Your function might require sensitive values, like API tokens, to run. You can
|
|
154
|
-
add [**secrets**](#npx-workers-secrets) to your function's run context. Secrets
|
|
155
|
-
are exposed to your function as environment variables.
|
|
156
|
-
|
|
157
|
-
Run the following to add secrets:
|
|
158
|
-
|
|
159
|
-
```shell
|
|
160
|
-
npx workers secrets set MY_SECRET_1=my-secret-value MY_SECRET_2=my-secret-value2
|
|
51
|
+
const worker = new Worker();
|
|
52
|
+
export default worker;
|
|
161
53
|
```
|
|
162
54
|
|
|
163
|
-
Then, you can reference these secret values in your function code using
|
|
164
|
-
`process.env`, e.g. `process.env.MY_SECRET_1`.
|
|
165
|
-
|
|
166
|
-
## Workers capabilities reference
|
|
167
|
-
|
|
168
55
|
### Sync
|
|
169
56
|
|
|
170
|
-
|
|
171
|
-
time a sync is run, data is upserted or deleted from the target Notion
|
|
172
|
-
collection so that the collection matches the source.
|
|
57
|
+
Syncs create or update a Notion database from your source data.
|
|
173
58
|
|
|
174
|
-
|
|
59
|
+
```ts
|
|
60
|
+
import * as Builder from "@project-ajax/sdk/builder";
|
|
61
|
+
import * as Schema from "@project-ajax/sdk/schema";
|
|
175
62
|
|
|
176
|
-
|
|
63
|
+
const worker = new Worker();
|
|
64
|
+
export default worker;
|
|
177
65
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
- `properties` (object): An object mapping property names to their values. Use functions from `@project-ajax/sdk/builder` to construct property values (e.g., `Builder.title()`, `Builder.richText()`).
|
|
187
|
-
|
|
188
|
-
### Tools
|
|
189
|
-
|
|
190
|
-
The **tool** capability allows custom agents in your Notion workspace to perform
|
|
191
|
-
actions. When you connect a worker to a custom agent, the agent can invoke your
|
|
192
|
-
tools based on their descriptions and schemas.
|
|
193
|
-
|
|
194
|
-
Tools use JSON Schema to define their input and output structures, and the SDK
|
|
195
|
-
validates data automatically.
|
|
196
|
-
|
|
197
|
-
#### Properties
|
|
198
|
-
|
|
199
|
-
- **`description`** (string, required): A clear description of what the tool does. This is shown to the AI agent to help it decide when to use the tool.
|
|
200
|
-
- **`schema`** (JSONSchemaType, required): JSON Schema definition for the tool's input parameters. The input will be validated against this schema before execution.
|
|
201
|
-
- **`outputSchema`** (JSONSchemaType, optional): JSON Schema definition for the tool's output. If provided, the output will be validated against this schema after execution.
|
|
202
|
-
- **`execute`** (function, required): Async function that performs the tool's action.
|
|
203
|
-
- **Parameters**: `input` (typed according to your schema) - The validated input parameters.
|
|
204
|
-
- **Returns**: Promise resolving to output data (validated against `outputSchema` if provided).
|
|
205
|
-
|
|
206
|
-
#### Error handling
|
|
207
|
-
|
|
208
|
-
The tool system automatically handles three types of errors:
|
|
209
|
-
|
|
210
|
-
- **`InvalidToolInputError`**: Thrown when input doesn't match the input schema.
|
|
211
|
-
- **`InvalidToolOutputError`**: Thrown when output doesn't match the output schema (if provided).
|
|
212
|
-
- **`ToolExecutionError`**: Thrown when the execute function throws an error.
|
|
213
|
-
|
|
214
|
-
All errors are automatically caught and returned in a structured format, so you don't need to handle them in your `execute` function.
|
|
215
|
-
|
|
216
|
-
#### JSON Schema types
|
|
217
|
-
|
|
218
|
-
Your schemas should use standard JSON Schema format. Common patterns:
|
|
219
|
-
|
|
220
|
-
**Object with required and optional properties:**
|
|
221
|
-
```typescript
|
|
222
|
-
{
|
|
223
|
-
type: "object",
|
|
224
|
-
properties: {
|
|
225
|
-
name: { type: "string" },
|
|
226
|
-
age: { type: "number", nullable: true },
|
|
227
|
-
active: { type: "boolean", nullable: true },
|
|
66
|
+
worker.sync("tasksSync", {
|
|
67
|
+
primaryKeyProperty: "ID",
|
|
68
|
+
schema: {
|
|
69
|
+
defaultName: "Tasks",
|
|
70
|
+
properties: {
|
|
71
|
+
Name: Schema.title(),
|
|
72
|
+
ID: Schema.richText(),
|
|
73
|
+
},
|
|
228
74
|
},
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
**Enums:**
|
|
244
|
-
```typescript
|
|
245
|
-
{
|
|
246
|
-
type: "string",
|
|
247
|
-
enum: ["option1", "option2", "option3"],
|
|
248
|
-
}
|
|
75
|
+
execute: async () => ({
|
|
76
|
+
objects: [
|
|
77
|
+
{
|
|
78
|
+
key: "1",
|
|
79
|
+
properties: {
|
|
80
|
+
Name: Builder.title("Write docs"),
|
|
81
|
+
ID: Builder.richText("1"),
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
done: true,
|
|
86
|
+
}),
|
|
87
|
+
});
|
|
249
88
|
```
|
|
250
89
|
|
|
251
|
-
|
|
90
|
+
### Tool
|
|
252
91
|
|
|
253
|
-
|
|
92
|
+
Tools are callable by Notion custom agents.
|
|
254
93
|
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
94
|
+
```ts
|
|
95
|
+
worker.tool("sayHello", {
|
|
96
|
+
title: "Say Hello",
|
|
97
|
+
description: "Return a greeting",
|
|
98
|
+
schema: {
|
|
99
|
+
type: "object",
|
|
100
|
+
properties: { name: { type: "string" } },
|
|
101
|
+
required: ["name"],
|
|
102
|
+
additionalProperties: false,
|
|
103
|
+
},
|
|
104
|
+
execute: ({ name }) => `Hello, ${name}`,
|
|
105
|
+
});
|
|
261
106
|
```
|
|
262
107
|
|
|
263
|
-
###
|
|
264
|
-
|
|
265
|
-
The **automation** capability allows you to create custom actions that can be
|
|
266
|
-
triggered from database automations in your Notion workspace. When you create a
|
|
267
|
-
database automation and select "Run worker" as an action, you can choose from
|
|
268
|
-
your deployed automation capabilities.
|
|
269
|
-
|
|
270
|
-
#### Properties
|
|
108
|
+
### Automation
|
|
271
109
|
|
|
272
|
-
|
|
273
|
-
- **`description`** (string, required): A brief description of what this automation does.
|
|
274
|
-
- **`execute`** (function, required): Async function that runs when the automation is triggered.
|
|
275
|
-
- **Parameters**: `context` (AutomationContext) - Context about the trigger, including:
|
|
276
|
-
- `actionType` (string): The type of automation action
|
|
277
|
-
- `pageId` (string, optional): ID of the page that triggered the automation
|
|
278
|
-
- `pageData` (object, optional): Full page object from Notion's Public API, including all properties
|
|
279
|
-
- **Returns**: Promise that resolves when the automation completes.
|
|
110
|
+
Automations run from Notion database buttons or automations.
|
|
280
111
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
```typescript
|
|
284
|
-
automation({
|
|
112
|
+
```ts
|
|
113
|
+
worker.automation("sendWelcomeEmail", {
|
|
285
114
|
title: "Send Welcome Email",
|
|
286
|
-
description: "
|
|
287
|
-
execute: async ({
|
|
288
|
-
|
|
289
|
-
const email = pageData.properties.Email;
|
|
290
|
-
await sendEmail(email);
|
|
291
|
-
}
|
|
115
|
+
description: "Runs from a database automation",
|
|
116
|
+
execute: async ({ pageId }) => {
|
|
117
|
+
console.log("Triggered for page", pageId);
|
|
292
118
|
},
|
|
293
|
-
})
|
|
119
|
+
});
|
|
294
120
|
```
|
|
295
121
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
The `workers` CLI provides commands to authenticate, deploy, execute, and manage
|
|
299
|
-
your Notion functions. All commands support global flags for configuration and
|
|
300
|
-
debugging.
|
|
301
|
-
|
|
302
|
-
### Global flags
|
|
303
|
-
|
|
304
|
-
These flags are available on all commands:
|
|
122
|
+
### OAuth
|
|
305
123
|
|
|
306
|
-
|
|
307
|
-
- **`--debug`**: Enable debug logging
|
|
124
|
+
OAuth capabilities let your worker access third-party APIs.
|
|
308
125
|
|
|
309
|
-
|
|
126
|
+
```ts
|
|
127
|
+
// Notion-managed provider
|
|
128
|
+
worker.oauth("googleAuth", { name: "my-google-auth", provider: "google" });
|
|
310
129
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
130
|
+
// User-managed provider
|
|
131
|
+
worker.oauth("acmeAuth", {
|
|
132
|
+
name: "acme-oauth",
|
|
133
|
+
authorizationEndpoint: "https://provider.example.com/oauth/authorize",
|
|
134
|
+
tokenEndpoint: "https://provider.example.com/oauth/token",
|
|
135
|
+
scope: "read write",
|
|
136
|
+
clientId: "YOUR_CLIENT_ID",
|
|
137
|
+
clientSecret: "YOUR_CLIENT_SECRET",
|
|
138
|
+
});
|
|
139
|
+
```
|
|
318
140
|
|
|
319
|
-
|
|
141
|
+
## Local Development
|
|
320
142
|
|
|
321
|
-
|
|
143
|
+
```shell
|
|
144
|
+
npm run dev # watch and run src/index.ts
|
|
145
|
+
npm run check # type-check
|
|
146
|
+
npm run build # emit dist/
|
|
147
|
+
```
|
|
322
148
|
|
|
323
|
-
|
|
149
|
+
## Workers CLI Commands
|
|
324
150
|
|
|
325
|
-
|
|
151
|
+
### `npx workers auth login`
|
|
152
|
+
Log in to Notion (use `--env=dev` for dev):
|
|
326
153
|
|
|
327
154
|
```shell
|
|
328
|
-
# Open browser to create a token
|
|
329
|
-
npx workers auth login
|
|
330
|
-
|
|
331
|
-
# Login with an existing token
|
|
332
|
-
npx workers auth login v1.user.wAFygwEZ-...
|
|
333
|
-
|
|
334
|
-
# Login to dev environment
|
|
335
155
|
npx workers auth login --env=dev
|
|
336
156
|
```
|
|
337
157
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
Display the currently configured authentication token.
|
|
341
|
-
|
|
342
|
-
**Example:**
|
|
158
|
+
### `npx workers auth show`
|
|
159
|
+
Show the active auth token:
|
|
343
160
|
|
|
344
161
|
```shell
|
|
345
162
|
npx workers auth show
|
|
346
163
|
```
|
|
347
164
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
Remove the currently configured authentication token.
|
|
351
|
-
|
|
352
|
-
**Example:**
|
|
165
|
+
### `npx workers auth logout`
|
|
166
|
+
Clear the stored auth token:
|
|
353
167
|
|
|
354
168
|
```shell
|
|
355
169
|
npx workers auth logout
|
|
356
170
|
```
|
|
357
171
|
|
|
358
172
|
### `npx workers deploy`
|
|
359
|
-
|
|
360
|
-
Deploy your worker to the Project Ajax platform. This command builds your worker
|
|
361
|
-
bundle, uploads it to Notion, and saves the worker configuration.
|
|
362
|
-
|
|
363
|
-
**Example:**
|
|
173
|
+
Build and upload your worker bundle:
|
|
364
174
|
|
|
365
175
|
```shell
|
|
366
176
|
npx workers deploy
|
|
367
177
|
```
|
|
368
178
|
|
|
369
|
-
The deploy command will:
|
|
370
|
-
|
|
371
|
-
1. Build your worker bundle from the current directory
|
|
372
|
-
2. Upload the bundle to Notion
|
|
373
|
-
3. Fetch and save worker capabilities
|
|
374
|
-
4. Store the worker ID in your config file
|
|
375
|
-
|
|
376
179
|
### `npx workers exec`
|
|
377
|
-
|
|
378
|
-
Execute a worker capability with optional function and arguments.
|
|
379
|
-
|
|
380
|
-
**Usage:**
|
|
381
|
-
|
|
382
|
-
```shell
|
|
383
|
-
npx workers exec <capabilityName> [functionName] [arg1=value1 arg2=value2...]
|
|
384
|
-
```
|
|
385
|
-
|
|
386
|
-
**Arguments:**
|
|
387
|
-
|
|
388
|
-
- `capabilityName` (required): Name of the capability to execute
|
|
389
|
-
- `arguments` (optional): Key-value pairs as arguments. Supports both `key=value` and `key value` formats.
|
|
390
|
-
|
|
391
|
-
**Flags:**
|
|
392
|
-
|
|
393
|
-
- `--output <mode>`: Output mode for results. Options:
|
|
394
|
-
- `none`: No output
|
|
395
|
-
- `full`: Complete output
|
|
396
|
-
- `pager`: Paginate long output (default)
|
|
397
|
-
|
|
398
|
-
**Examples:**
|
|
180
|
+
Run a sync or tool capability:
|
|
399
181
|
|
|
400
182
|
```shell
|
|
401
|
-
# Execute a sync capability
|
|
402
183
|
npx workers exec tasksSync
|
|
403
184
|
```
|
|
404
185
|
|
|
405
|
-
### `npx workers capabilities`
|
|
406
|
-
|
|
407
|
-
Commands for managing worker capabilities.
|
|
408
|
-
|
|
409
|
-
#### `npx workers capabilities list`
|
|
410
|
-
|
|
411
|
-
List all capabilities for the deployed worker.
|
|
412
|
-
|
|
413
|
-
**Example:**
|
|
186
|
+
### `npx workers capabilities list`
|
|
187
|
+
List deployed capabilities:
|
|
414
188
|
|
|
415
189
|
```shell
|
|
416
190
|
npx workers capabilities list
|
|
417
191
|
```
|
|
418
192
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
### `npx workers secrets`
|
|
423
|
-
|
|
424
|
-
Commands for managing worker secrets. Secrets are exposed to your functions as
|
|
425
|
-
environment variables via `process.env`.
|
|
426
|
-
|
|
427
|
-
#### `npx workers secrets set <key> <value> [<key2> <value2>...]`
|
|
428
|
-
|
|
429
|
-
Set one or more secrets for your worker. Supports multiple formats:
|
|
430
|
-
|
|
431
|
-
**Formats:**
|
|
432
|
-
|
|
433
|
-
- Space-separated: `key value`
|
|
434
|
-
- Equals-separated: `key=value`
|
|
435
|
-
- Colon-separated: `key:value`
|
|
436
|
-
|
|
437
|
-
**Examples:**
|
|
193
|
+
### `npx workers capabilities enable`
|
|
194
|
+
Enable a sync capability:
|
|
438
195
|
|
|
439
196
|
```shell
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
# Set multiple secrets (space-separated)
|
|
444
|
-
npx workers secrets set API_KEY my-key API_SECRET my-secret
|
|
197
|
+
npx workers capabilities enable tasksSync
|
|
198
|
+
```
|
|
445
199
|
|
|
446
|
-
|
|
447
|
-
|
|
200
|
+
### `npx workers capabilities disable`
|
|
201
|
+
Disable a sync capability:
|
|
448
202
|
|
|
449
|
-
|
|
450
|
-
npx workers
|
|
203
|
+
```shell
|
|
204
|
+
npx workers capabilities disable tasksSync
|
|
451
205
|
```
|
|
452
206
|
|
|
453
|
-
|
|
207
|
+
### `npx workers secrets set`
|
|
208
|
+
Store secrets for runtime access:
|
|
454
209
|
|
|
455
|
-
|
|
456
|
-
|
|
210
|
+
```shell
|
|
211
|
+
npx workers secrets set API_KEY=my-secret
|
|
212
|
+
```
|
|
457
213
|
|
|
458
|
-
|
|
214
|
+
### `npx workers secrets list`
|
|
215
|
+
List secret keys:
|
|
459
216
|
|
|
460
217
|
```shell
|
|
461
218
|
npx workers secrets list
|
|
462
219
|
```
|
|
463
220
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
Remove a secret from your worker.
|
|
467
|
-
|
|
468
|
-
**Arguments:**
|
|
469
|
-
|
|
470
|
-
- `key` (required): The secret key name to remove
|
|
471
|
-
|
|
472
|
-
**Example:**
|
|
221
|
+
### `npx workers secrets rm`
|
|
222
|
+
Remove a secret:
|
|
473
223
|
|
|
474
224
|
```shell
|
|
475
225
|
npx workers secrets rm API_KEY
|
|
476
226
|
```
|
|
477
227
|
|
|
478
|
-
### `npx workers oauth`
|
|
228
|
+
### `npx workers oauth start`
|
|
229
|
+
Start an OAuth flow for a capability:
|
|
479
230
|
|
|
480
|
-
|
|
231
|
+
```shell
|
|
232
|
+
npx workers oauth start googleAuth
|
|
233
|
+
```
|
|
481
234
|
|
|
482
|
-
|
|
235
|
+
### `npx workers env pull`
|
|
236
|
+
Write remote env vars to a local `.env` file:
|
|
483
237
|
|
|
484
|
-
|
|
485
|
-
|
|
238
|
+
```shell
|
|
239
|
+
npx workers env pull .env
|
|
240
|
+
```
|
|
486
241
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
contexts, pass the key explicitly.
|
|
242
|
+
### `npx workers runs list`
|
|
243
|
+
List recent runs:
|
|
490
244
|
|
|
491
245
|
```shell
|
|
492
|
-
|
|
493
|
-
npx workers oauth start
|
|
494
|
-
|
|
495
|
-
# Start OAuth for a specific OAuth capability
|
|
496
|
-
npx workers oauth start <capabilityKey>
|
|
246
|
+
npx workers runs list
|
|
497
247
|
```
|
|
498
248
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
### Configuration file
|
|
249
|
+
### `npx workers runs logs`
|
|
250
|
+
Fetch logs for a run:
|
|
502
251
|
|
|
503
|
-
|
|
504
|
-
|
|
252
|
+
```shell
|
|
253
|
+
npx workers runs logs <runId>
|
|
254
|
+
```
|
|
505
255
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
- **`workerId`**: The ID of your deployed worker
|
|
256
|
+
### `npx workers bundle download`
|
|
257
|
+
Download the deployed bundle:
|
|
509
258
|
|
|
510
|
-
|
|
259
|
+
```shell
|
|
260
|
+
npx workers bundle download
|
|
261
|
+
```
|
package/template/src/index.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Worker } from "@project-ajax/sdk";
|
|
2
2
|
import * as Builder from "@project-ajax/sdk/builder";
|
|
3
3
|
import * as Schema from "@project-ajax/sdk/schema";
|
|
4
4
|
|
|
5
|
+
const worker = new Worker();
|
|
6
|
+
export default worker;
|
|
7
|
+
|
|
5
8
|
// Sample data for demonstration
|
|
6
9
|
const sampleTasks = [
|
|
7
10
|
{
|
|
@@ -25,7 +28,7 @@ const sampleTasks = [
|
|
|
25
28
|
];
|
|
26
29
|
|
|
27
30
|
// Example sync worker that syncs sample tasks to a database
|
|
28
|
-
|
|
31
|
+
worker.sync("tasksSync", {
|
|
29
32
|
primaryKeyProperty: "Task ID",
|
|
30
33
|
|
|
31
34
|
// Optional: How often the sync should run. Defaults to "continuous".
|
|
@@ -85,7 +88,7 @@ export const tasksSync = sync({
|
|
|
85
88
|
});
|
|
86
89
|
|
|
87
90
|
// Example agent tool for retrieving task information
|
|
88
|
-
|
|
91
|
+
worker.tool("taskSearchTool", {
|
|
89
92
|
title: "Task Search",
|
|
90
93
|
description:
|
|
91
94
|
"Look up sample tasks by ID or keyword. Helpful for demonstrating agent tool calls.",
|
|
@@ -154,7 +157,7 @@ export const taskSearchTool = tool({
|
|
|
154
157
|
});
|
|
155
158
|
|
|
156
159
|
// Example automation that runs when triggered from a database automation
|
|
157
|
-
|
|
160
|
+
worker.automation("completeTaskAutomation", {
|
|
158
161
|
title: "Mark Task Complete",
|
|
159
162
|
description: "Automatically marks a task as complete when triggered",
|
|
160
163
|
execute: async ({ pageId, actionType, pageData }) => {
|