@plotday/twister 0.47.0 → 0.49.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/bin/commands/generate.js +5 -5
- package/bin/commands/generate.js.map +1 -1
- package/bin/templates/AGENTS.template.md +8 -2
- package/bin/utils/bundle.js +14 -0
- package/bin/utils/bundle.js.map +1 -1
- package/cli/templates/AGENTS.template.md +8 -2
- package/dist/connector.d.ts +67 -7
- package/dist/connector.d.ts.map +1 -1
- package/dist/connector.js +15 -5
- package/dist/connector.js.map +1 -1
- package/dist/docs/assets/hierarchy.js +1 -1
- package/dist/docs/assets/navigation.js +1 -1
- package/dist/docs/assets/search.js +1 -1
- package/dist/docs/classes/index.Connector.html +58 -49
- package/dist/docs/classes/index.Imap.html +1 -1
- package/dist/docs/classes/index.Options.html +1 -1
- package/dist/docs/classes/index.Smtp.html +1 -1
- package/dist/docs/classes/tools_ai.AI.html +1 -1
- package/dist/docs/classes/tools_callbacks.Callbacks.html +1 -1
- package/dist/docs/classes/tools_integrations.Integrations.html +21 -5
- package/dist/docs/classes/tools_network.Network.html +1 -1
- package/dist/docs/classes/tools_plot.Plot.html +1 -1
- package/dist/docs/classes/tools_store.Store.html +1 -1
- package/dist/docs/classes/tools_tasks.Tasks.html +1 -1
- package/dist/docs/classes/tools_twists.Twists.html +1 -1
- package/dist/docs/classes/twist.Twist.html +28 -28
- package/dist/docs/documents/Building_Connectors.html +8 -1
- package/dist/docs/documents/CLI_Reference.html +6 -4
- package/dist/docs/enums/tag.Tag.html +11 -1
- package/dist/docs/enums/tools_integrations.AuthProvider.html +14 -12
- package/dist/docs/hierarchy.html +1 -1
- package/dist/docs/media/AGENTS.md +298 -775
- package/dist/docs/media/MULTI_USER_AUTH.md +6 -4
- package/dist/docs/media/SYNC_STRATEGIES.md +20 -14
- package/dist/docs/modules/index.html +1 -1
- package/dist/docs/types/index.CreateLinkDraft.html +7 -12
- package/dist/docs/types/index.NoteWriteBackResult.html +38 -0
- package/dist/docs/types/tools_integrations.ArchiveLinkFilter.html +5 -5
- package/dist/docs/types/tools_integrations.AuthToken.html +4 -4
- package/dist/docs/types/tools_integrations.Authorization.html +4 -4
- package/dist/llm-docs/connector.d.ts +1 -1
- package/dist/llm-docs/connector.d.ts.map +1 -1
- package/dist/llm-docs/connector.js +1 -1
- package/dist/llm-docs/connector.js.map +1 -1
- package/dist/llm-docs/tag.d.ts +1 -1
- package/dist/llm-docs/tag.d.ts.map +1 -1
- package/dist/llm-docs/tag.js +1 -1
- package/dist/llm-docs/tag.js.map +1 -1
- package/dist/llm-docs/tools/integrations.d.ts +1 -1
- package/dist/llm-docs/tools/integrations.d.ts.map +1 -1
- package/dist/llm-docs/tools/integrations.js +1 -1
- package/dist/llm-docs/tools/integrations.js.map +1 -1
- package/dist/llm-docs/twist-guide-template.d.ts +1 -1
- package/dist/llm-docs/twist-guide-template.d.ts.map +1 -1
- package/dist/llm-docs/twist-guide-template.js +1 -1
- package/dist/llm-docs/twist-guide-template.js.map +1 -1
- package/dist/llm-docs/twist.d.ts +1 -1
- package/dist/llm-docs/twist.d.ts.map +1 -1
- package/dist/llm-docs/twist.js +1 -1
- package/dist/llm-docs/twist.js.map +1 -1
- package/dist/tag.d.ts +11 -1
- package/dist/tag.d.ts.map +1 -1
- package/dist/tag.js +10 -0
- package/dist/tag.js.map +1 -1
- package/dist/tools/integrations.d.ts +25 -1
- package/dist/tools/integrations.d.ts.map +1 -1
- package/dist/tools/integrations.js +2 -0
- package/dist/tools/integrations.js.map +1 -1
- package/dist/twist-guide.d.ts +1 -1
- package/dist/twist-guide.d.ts.map +1 -1
- package/dist/twist.d.ts +2 -1
- package/dist/twist.d.ts.map +1 -1
- package/dist/twist.js.map +1 -1
- package/dist/utils/markdown.d.ts +27 -0
- package/dist/utils/markdown.d.ts.map +1 -0
- package/dist/utils/markdown.js +82 -0
- package/dist/utils/markdown.js.map +1 -0
- package/package.json +7 -1
- package/src/connector.ts +427 -0
- package/src/creator-docs.ts +29 -0
- package/src/index.ts +10 -0
- package/src/llm-docs/connector.ts +8 -0
- package/src/llm-docs/index.ts +48 -0
- package/src/llm-docs/options.ts +8 -0
- package/src/llm-docs/plot.ts +8 -0
- package/src/llm-docs/schedule.ts +8 -0
- package/src/llm-docs/tag.ts +8 -0
- package/src/llm-docs/tool.ts +8 -0
- package/src/llm-docs/tools/ai.ts +8 -0
- package/src/llm-docs/tools/callbacks.ts +8 -0
- package/src/llm-docs/tools/imap.ts +8 -0
- package/src/llm-docs/tools/integrations.ts +8 -0
- package/src/llm-docs/tools/network.ts +8 -0
- package/src/llm-docs/tools/plot.ts +8 -0
- package/src/llm-docs/tools/smtp.ts +8 -0
- package/src/llm-docs/tools/store.ts +8 -0
- package/src/llm-docs/tools/tasks.ts +8 -0
- package/src/llm-docs/tools/twists.ts +8 -0
- package/src/llm-docs/twist-guide-template.ts +8 -0
- package/src/llm-docs/twist.ts +8 -0
- package/src/options.ts +115 -0
- package/src/plot.ts +1068 -0
- package/src/schedule.ts +203 -0
- package/src/tag.ts +54 -0
- package/src/tool.ts +377 -0
- package/src/tools/ai.ts +845 -0
- package/src/tools/callbacks.ts +134 -0
- package/src/tools/imap.ts +266 -0
- package/src/tools/index.ts +10 -0
- package/src/tools/integrations.ts +352 -0
- package/src/tools/network.ts +240 -0
- package/src/tools/plot.ts +692 -0
- package/src/tools/smtp.ts +166 -0
- package/src/tools/store.ts +149 -0
- package/src/tools/tasks.ts +137 -0
- package/src/tools/twists.ts +228 -0
- package/src/twist-guide.ts +9 -0
- package/src/twist.ts +436 -0
- package/src/utils/hash.ts +8 -0
- package/src/utils/markdown.ts +94 -0
- package/src/utils/serializable.ts +54 -0
- package/src/utils/types.ts +130 -0
- package/src/utils/uuid.ts +9 -0
package/src/schedule.ts
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { type Tag } from "./tag";
|
|
2
|
+
import {
|
|
3
|
+
type Actor,
|
|
4
|
+
type ActorId,
|
|
5
|
+
type NewActor,
|
|
6
|
+
type NewTags,
|
|
7
|
+
type Tags,
|
|
8
|
+
} from "./plot";
|
|
9
|
+
import { Uuid } from "./utils/uuid";
|
|
10
|
+
|
|
11
|
+
export { Uuid } from "./utils/uuid";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Represents a schedule entry for a thread.
|
|
15
|
+
*
|
|
16
|
+
* Schedules define when a thread occurs in time. A thread may have zero or more schedules:
|
|
17
|
+
* - Shared schedules (userId is null): visible to all members of the thread's priority
|
|
18
|
+
* - Per-user schedules (userId set): private ordering/scheduling for a specific user
|
|
19
|
+
*
|
|
20
|
+
* For recurring events in the SDK, start/end represent the first occurrence's
|
|
21
|
+
* time. In the database, the `at`/`on` range is expanded to span from the first
|
|
22
|
+
* occurrence start to the last occurrence end (or open-ended if no fixed end).
|
|
23
|
+
* The `duration` column stores the per-occurrence duration, enabling range overlap
|
|
24
|
+
* queries to correctly find all recurring events with occurrences in a given window.
|
|
25
|
+
*/
|
|
26
|
+
export type Schedule = {
|
|
27
|
+
/** When this schedule was created */
|
|
28
|
+
created: Date;
|
|
29
|
+
/** Whether this schedule has been archived */
|
|
30
|
+
archived: boolean;
|
|
31
|
+
/** If set, this is a per-user schedule visible only to this user */
|
|
32
|
+
userId: ActorId | null;
|
|
33
|
+
/** Per-user ordering within a day (only set for per-user schedules) */
|
|
34
|
+
order: number | null;
|
|
35
|
+
/**
|
|
36
|
+
* Start time of the schedule.
|
|
37
|
+
* Date object for timed events, date string in "YYYY-MM-DD" format for all-day events.
|
|
38
|
+
*/
|
|
39
|
+
start: Date | string | null;
|
|
40
|
+
/**
|
|
41
|
+
* End time of the schedule.
|
|
42
|
+
* Date object for timed events, date string in "YYYY-MM-DD" format for all-day events.
|
|
43
|
+
*/
|
|
44
|
+
end: Date | string | null;
|
|
45
|
+
/** Recurrence rule in RFC 5545 RRULE format (e.g., "FREQ=WEEKLY;BYDAY=MO,WE,FR") */
|
|
46
|
+
recurrenceRule: string | null;
|
|
47
|
+
/** Duration of each occurrence in milliseconds (required for recurring schedules) */
|
|
48
|
+
duration: number | null;
|
|
49
|
+
/** Array of dates to exclude from the recurrence pattern */
|
|
50
|
+
recurrenceExdates: Date[] | null;
|
|
51
|
+
/**
|
|
52
|
+
* For occurrence exceptions: the original date/time of this occurrence in the series.
|
|
53
|
+
* Format: Date object or "YYYY-MM-DD" for all-day events.
|
|
54
|
+
*/
|
|
55
|
+
occurrence: Date | string | null;
|
|
56
|
+
/** Contacts invited to this schedule (attendees/participants) */
|
|
57
|
+
contacts: ScheduleContact[];
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export type ScheduleContactStatus = "attend" | "skip";
|
|
61
|
+
export type ScheduleContactRole = "organizer" | "required" | "optional";
|
|
62
|
+
|
|
63
|
+
export type ScheduleContact = {
|
|
64
|
+
contact: Actor;
|
|
65
|
+
status: ScheduleContactStatus | null;
|
|
66
|
+
role: ScheduleContactRole;
|
|
67
|
+
archived: boolean;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export type NewScheduleContact = {
|
|
71
|
+
contact: NewActor;
|
|
72
|
+
status?: ScheduleContactStatus | null;
|
|
73
|
+
role?: ScheduleContactRole | null;
|
|
74
|
+
archived?: boolean;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Type for creating new schedules.
|
|
79
|
+
*
|
|
80
|
+
* Requires `threadId` and `start`. All other fields are optional.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* // Simple timed event
|
|
85
|
+
* const schedule: NewSchedule = {
|
|
86
|
+
* threadId: threadId,
|
|
87
|
+
* start: new Date("2025-03-15T10:00:00Z"),
|
|
88
|
+
* end: new Date("2025-03-15T11:00:00Z")
|
|
89
|
+
* };
|
|
90
|
+
*
|
|
91
|
+
* // All-day event
|
|
92
|
+
* const allDay: NewSchedule = {
|
|
93
|
+
* threadId: threadId,
|
|
94
|
+
* start: "2025-03-15",
|
|
95
|
+
* end: "2025-03-16"
|
|
96
|
+
* };
|
|
97
|
+
*
|
|
98
|
+
* // Recurring weekly event
|
|
99
|
+
* const recurring: NewSchedule = {
|
|
100
|
+
* threadId: threadId,
|
|
101
|
+
* start: new Date("2025-01-20T14:00:00Z"),
|
|
102
|
+
* end: new Date("2025-01-20T15:00:00Z"),
|
|
103
|
+
* recurrenceRule: "FREQ=WEEKLY;BYDAY=MO",
|
|
104
|
+
* recurrenceUntil: new Date("2025-06-30")
|
|
105
|
+
* };
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export type NewSchedule = {
|
|
109
|
+
/** The thread this schedule belongs to */
|
|
110
|
+
threadId: Uuid;
|
|
111
|
+
/**
|
|
112
|
+
* Start time. Date for timed events, "YYYY-MM-DD" for all-day.
|
|
113
|
+
* Determines whether the schedule uses `at` (timed) or `on` (all-day) storage.
|
|
114
|
+
*/
|
|
115
|
+
start: Date | string;
|
|
116
|
+
/** End time. Date for timed events, "YYYY-MM-DD" for all-day. */
|
|
117
|
+
end?: Date | string | null;
|
|
118
|
+
/** Recurrence rule in RFC 5545 RRULE format */
|
|
119
|
+
recurrenceRule?: string | null;
|
|
120
|
+
/**
|
|
121
|
+
* For recurring schedules, the last occurrence date (inclusive).
|
|
122
|
+
* When both recurrenceCount and recurrenceUntil are provided, recurrenceCount takes precedence.
|
|
123
|
+
*/
|
|
124
|
+
recurrenceUntil?: Date | string | null;
|
|
125
|
+
/**
|
|
126
|
+
* For recurring schedules, the number of occurrences to generate.
|
|
127
|
+
* Takes precedence over recurrenceUntil if both are provided.
|
|
128
|
+
*/
|
|
129
|
+
recurrenceCount?: number | null;
|
|
130
|
+
/** Array of dates to exclude from the recurrence pattern */
|
|
131
|
+
recurrenceExdates?: Date[] | null;
|
|
132
|
+
/**
|
|
133
|
+
* For occurrence exceptions: the original date/time of this occurrence.
|
|
134
|
+
*/
|
|
135
|
+
occurrence?: Date | string | null;
|
|
136
|
+
/** If set, this is a per-user schedule for the specified user */
|
|
137
|
+
userId?: ActorId | null;
|
|
138
|
+
/** Per-user ordering (only valid with userId) */
|
|
139
|
+
order?: number | null;
|
|
140
|
+
/** Whether to archive this schedule */
|
|
141
|
+
archived?: boolean;
|
|
142
|
+
/** Contacts to upsert on this schedule. Upserted by contact identity. */
|
|
143
|
+
contacts?: NewScheduleContact[];
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Represents a specific instance of a recurring schedule.
|
|
148
|
+
* All field values are computed by merging the recurring schedule's
|
|
149
|
+
* defaults with any occurrence-specific overrides.
|
|
150
|
+
*/
|
|
151
|
+
export type ScheduleOccurrence = {
|
|
152
|
+
/**
|
|
153
|
+
* Original date/datetime of this occurrence.
|
|
154
|
+
* Use start for the occurrence's current start time.
|
|
155
|
+
*/
|
|
156
|
+
occurrence: Date | string;
|
|
157
|
+
|
|
158
|
+
/** The recurring schedule of which this is an occurrence */
|
|
159
|
+
schedule: Schedule;
|
|
160
|
+
|
|
161
|
+
/** Effective start for this occurrence (series default + override) */
|
|
162
|
+
start: Date | string;
|
|
163
|
+
/** Effective end for this occurrence */
|
|
164
|
+
end: Date | string | null;
|
|
165
|
+
|
|
166
|
+
/** Tags for this occurrence */
|
|
167
|
+
tags: Tags;
|
|
168
|
+
|
|
169
|
+
/** True if the occurrence is archived */
|
|
170
|
+
archived: boolean;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Type for creating or updating schedule occurrences.
|
|
175
|
+
*/
|
|
176
|
+
export type NewScheduleOccurrence = Pick<
|
|
177
|
+
ScheduleOccurrence,
|
|
178
|
+
"occurrence" | "start"
|
|
179
|
+
> &
|
|
180
|
+
Partial<
|
|
181
|
+
Omit<ScheduleOccurrence, "occurrence" | "start" | "schedule" | "tags">
|
|
182
|
+
> & {
|
|
183
|
+
/** Tags for this occurrence */
|
|
184
|
+
tags?: NewTags;
|
|
185
|
+
|
|
186
|
+
/** Add or remove the twist's tags on this occurrence */
|
|
187
|
+
twistTags?: Partial<Record<Tag, boolean>>;
|
|
188
|
+
|
|
189
|
+
/** Whether this occurrence should be marked as unread */
|
|
190
|
+
unread?: boolean;
|
|
191
|
+
|
|
192
|
+
/** Contacts to upsert on this occurrence's schedule */
|
|
193
|
+
contacts?: NewScheduleContact[];
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Type for updating schedule occurrences inline.
|
|
198
|
+
*/
|
|
199
|
+
export type ScheduleOccurrenceUpdate = Pick<
|
|
200
|
+
NewScheduleOccurrence,
|
|
201
|
+
"occurrence"
|
|
202
|
+
> &
|
|
203
|
+
Partial<Omit<NewScheduleOccurrence, "occurrence" | "schedule">>;
|
package/src/tag.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thread tags. Three types:
|
|
3
|
+
* 1. Special tags, which trigger other behaviors
|
|
4
|
+
* 2. Toggle tags, which anyone can toggle a shared value on or off
|
|
5
|
+
* 3. Count tags, where everyone can add or remove their own
|
|
6
|
+
*/
|
|
7
|
+
export enum Tag {
|
|
8
|
+
// Special tags
|
|
9
|
+
Todo = 1,
|
|
10
|
+
Done = 3,
|
|
11
|
+
|
|
12
|
+
// Toggle tags
|
|
13
|
+
Pinned = 100,
|
|
14
|
+
Urgent = 101,
|
|
15
|
+
Goal = 103,
|
|
16
|
+
Decision = 104,
|
|
17
|
+
Waiting = 105,
|
|
18
|
+
Blocked = 106,
|
|
19
|
+
Warning = 107,
|
|
20
|
+
Question = 108,
|
|
21
|
+
Twist = 109,
|
|
22
|
+
Star = 110,
|
|
23
|
+
Idea = 111,
|
|
24
|
+
|
|
25
|
+
// Count tags
|
|
26
|
+
Yes = 1000,
|
|
27
|
+
No = 1001,
|
|
28
|
+
Volunteer = 1002,
|
|
29
|
+
Tada = 1003,
|
|
30
|
+
Fire = 1004,
|
|
31
|
+
Totally = 1005,
|
|
32
|
+
Looking = 1006,
|
|
33
|
+
Love = 1007,
|
|
34
|
+
Rocket = 1008,
|
|
35
|
+
Sparkles = 1009,
|
|
36
|
+
Thanks = 1010,
|
|
37
|
+
Smile = 1011,
|
|
38
|
+
Wave = 1012,
|
|
39
|
+
Praise = 1015,
|
|
40
|
+
Applause = 1016,
|
|
41
|
+
Cool = 1017,
|
|
42
|
+
Sad = 1018,
|
|
43
|
+
Reply = 1019,
|
|
44
|
+
Thinking = 1013,
|
|
45
|
+
Remember = 1014,
|
|
46
|
+
Agreed = 1020,
|
|
47
|
+
Relieved = 1021,
|
|
48
|
+
Send = 1022,
|
|
49
|
+
Noted = 1023,
|
|
50
|
+
Laugh = 1024,
|
|
51
|
+
Surprised = 1025,
|
|
52
|
+
Confused = 1026,
|
|
53
|
+
Dismayed = 1027,
|
|
54
|
+
}
|
package/src/tool.ts
ADDED
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type Actor,
|
|
3
|
+
} from "./plot";
|
|
4
|
+
import type { Callback } from "./tools/callbacks";
|
|
5
|
+
import type {
|
|
6
|
+
InferOptions,
|
|
7
|
+
InferTools,
|
|
8
|
+
Serializable,
|
|
9
|
+
ToolBuilder,
|
|
10
|
+
ToolShed,
|
|
11
|
+
} from "./utils/types";
|
|
12
|
+
|
|
13
|
+
export type { ToolBuilder };
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Abstrtact parent for both built-in tools and regular Tools.
|
|
17
|
+
* Regular tools extend Tool.
|
|
18
|
+
*/
|
|
19
|
+
export abstract class ITool {}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Base class for regular tools.
|
|
23
|
+
*
|
|
24
|
+
* Regular tools run in isolation and can only access other tools declared
|
|
25
|
+
* in their build method. They are ideal for external API integrations
|
|
26
|
+
* and reusable functionality that doesn't require Plot's internal infrastructure.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* class GoogleCalendarTool extends Tool<GoogleCalendarTool> {
|
|
31
|
+
* constructor(id: string, options: { clientId: string }) {
|
|
32
|
+
* super(id, options);
|
|
33
|
+
* }
|
|
34
|
+
*
|
|
35
|
+
* build(tools: ToolBuilder) {
|
|
36
|
+
* return {
|
|
37
|
+
* auth: tools.build(Integrations),
|
|
38
|
+
* network: tools.build(Network),
|
|
39
|
+
* };
|
|
40
|
+
* }
|
|
41
|
+
*
|
|
42
|
+
* async getCalendars() {
|
|
43
|
+
* const token = await this.tools.auth.get(...);
|
|
44
|
+
* // Implementation
|
|
45
|
+
* }
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export abstract class Tool<TSelf> implements ITool {
|
|
50
|
+
constructor(
|
|
51
|
+
protected id: string,
|
|
52
|
+
protected options: InferOptions<TSelf>,
|
|
53
|
+
private toolShed: ToolShed
|
|
54
|
+
) {}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Gets the initialized tools for this tool.
|
|
58
|
+
* @throws Error if called before initialization is complete
|
|
59
|
+
*/
|
|
60
|
+
protected get tools() {
|
|
61
|
+
return this.toolShed.getTools<InferTools<TSelf>>();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Declares tool dependencies for this tool.
|
|
66
|
+
* Return an object mapping tool names to build() promises.
|
|
67
|
+
* Default implementation returns empty object (no custom tools).
|
|
68
|
+
*
|
|
69
|
+
* @param build - The build function to use for declaring dependencies
|
|
70
|
+
* @returns Object mapping tool names to tool promises
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* build(build: ToolBuilder) {
|
|
75
|
+
* return {
|
|
76
|
+
* network: build(Network, { urls: ["https://api.example.com/*"] }),
|
|
77
|
+
* };
|
|
78
|
+
* }
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
82
|
+
build(build: ToolBuilder): Record<string, Promise<ITool>> {
|
|
83
|
+
return {};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Creates a persistent callback to a method on this tool.
|
|
88
|
+
*
|
|
89
|
+
* ExtraArgs are strongly typed to match the method's signature.
|
|
90
|
+
*
|
|
91
|
+
* @param fn - The method to callback
|
|
92
|
+
* @param extraArgs - Additional arguments to pass (type-checked, must be serializable)
|
|
93
|
+
* @returns Promise resolving to a persistent callback token
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```typescript
|
|
97
|
+
* const callback = await this.callback(this.onWebhook, "calendar", 123);
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
protected async callback<
|
|
101
|
+
TArgs extends Serializable[],
|
|
102
|
+
Fn extends (...args: TArgs) => any
|
|
103
|
+
>(fn: Fn, ...extraArgs: TArgs): Promise<Callback> {
|
|
104
|
+
return this.tools.callbacks.create(fn, ...extraArgs);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Deletes a specific callback by its token.
|
|
109
|
+
*
|
|
110
|
+
* @param token - The callback token to delete
|
|
111
|
+
* @returns Promise that resolves when the callback is deleted
|
|
112
|
+
*/
|
|
113
|
+
protected async deleteCallback(token: Callback): Promise<void> {
|
|
114
|
+
return this.tools.callbacks.delete(token);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Deletes all callbacks for this tool.
|
|
119
|
+
*
|
|
120
|
+
* @returns Promise that resolves when all callbacks are deleted
|
|
121
|
+
*/
|
|
122
|
+
protected async deleteAllCallbacks(): Promise<void> {
|
|
123
|
+
return this.tools.callbacks.deleteAll();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Executes a callback by its token inline in the current execution.
|
|
128
|
+
*
|
|
129
|
+
* **Use `this.runTask()` instead for batch continuations and long-running work.**
|
|
130
|
+
* `this.run()` executes inline, sharing the current request count (~1000 limit)
|
|
131
|
+
* and blocking the HTTP response. This causes timeouts when used in lifecycle
|
|
132
|
+
* methods like `onChannelEnabled` or `syncBatch` continuations.
|
|
133
|
+
*
|
|
134
|
+
* `this.run()` is appropriate when you need the callback's **return value** —
|
|
135
|
+
* e.g., running a parent callback token that returns data. For fire-and-forget
|
|
136
|
+
* work, always prefer `this.runTask()`.
|
|
137
|
+
*
|
|
138
|
+
* @param token - The callback token to execute
|
|
139
|
+
* @param args - Optional arguments to pass to the callback
|
|
140
|
+
* @returns Promise resolving to the callback result
|
|
141
|
+
*/
|
|
142
|
+
protected async run(token: Callback, ...args: any[]): Promise<any> {
|
|
143
|
+
return this.tools.callbacks.run(token, ...args);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Retrieves a value from persistent storage by key.
|
|
148
|
+
*
|
|
149
|
+
* Values are automatically deserialized using SuperJSON, which
|
|
150
|
+
* properly restores Date objects, Maps, Sets, and other complex types.
|
|
151
|
+
*
|
|
152
|
+
* @template T - The expected type of the stored value (must be Serializable)
|
|
153
|
+
* @param key - The storage key to retrieve
|
|
154
|
+
* @returns Promise resolving to the stored value or null
|
|
155
|
+
*/
|
|
156
|
+
protected async get<T extends Serializable>(key: string): Promise<T | null> {
|
|
157
|
+
return this.tools.store.get(key);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Stores a value in persistent storage.
|
|
162
|
+
*
|
|
163
|
+
* The value will be serialized using SuperJSON and stored persistently.
|
|
164
|
+
* SuperJSON automatically handles Date objects, Maps, Sets, undefined values,
|
|
165
|
+
* and other complex types that standard JSON doesn't support.
|
|
166
|
+
*
|
|
167
|
+
* **Important**: Functions and Symbols cannot be stored.
|
|
168
|
+
* **For function references**: Use callbacks instead of storing functions directly.
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```typescript
|
|
172
|
+
* // ✅ Date objects are preserved
|
|
173
|
+
* await this.set("sync_state", {
|
|
174
|
+
* lastSync: new Date(),
|
|
175
|
+
* minDate: new Date(2024, 0, 1)
|
|
176
|
+
* });
|
|
177
|
+
*
|
|
178
|
+
* // ✅ undefined is now supported
|
|
179
|
+
* await this.set("data", { name: "test", optional: undefined });
|
|
180
|
+
*
|
|
181
|
+
* // ✅ Arrays with undefined are supported
|
|
182
|
+
* await this.set("items", [1, undefined, 3]);
|
|
183
|
+
* await this.set("items", [1, null, 3]); // Also works
|
|
184
|
+
*
|
|
185
|
+
* // ✅ Maps and Sets are supported
|
|
186
|
+
* await this.set("mapping", new Map([["key", "value"]]));
|
|
187
|
+
* await this.set("tags", new Set(["tag1", "tag2"]));
|
|
188
|
+
*
|
|
189
|
+
* // ❌ WRONG: Cannot store functions directly
|
|
190
|
+
* await this.set("handler", this.myHandler);
|
|
191
|
+
*
|
|
192
|
+
* // ✅ CORRECT: Create a callback token first
|
|
193
|
+
* const token = await this.callback(this.myHandler, "arg1", "arg2");
|
|
194
|
+
* await this.set("handler_token", token);
|
|
195
|
+
*
|
|
196
|
+
* // Later, execute the callback
|
|
197
|
+
* const token = await this.get<string>("handler_token");
|
|
198
|
+
* await this.run(token, args);
|
|
199
|
+
* ```
|
|
200
|
+
*
|
|
201
|
+
* @template T - The type of value being stored (must be Serializable)
|
|
202
|
+
* @param key - The storage key to use
|
|
203
|
+
* @param value - The value to store (must be SuperJSON-serializable)
|
|
204
|
+
* @returns Promise that resolves when the value is stored
|
|
205
|
+
*/
|
|
206
|
+
protected async set<T extends Serializable>(
|
|
207
|
+
key: string,
|
|
208
|
+
value: T
|
|
209
|
+
): Promise<void> {
|
|
210
|
+
return this.tools.store.set(key, value);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Lists all storage keys matching a prefix.
|
|
215
|
+
*
|
|
216
|
+
* @param prefix - The prefix to match keys against
|
|
217
|
+
* @returns Promise resolving to an array of matching key strings
|
|
218
|
+
*/
|
|
219
|
+
protected async list(prefix: string): Promise<string[]> {
|
|
220
|
+
return this.tools.store.list(prefix);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Removes a specific key from persistent storage.
|
|
225
|
+
*
|
|
226
|
+
* @param key - The storage key to remove
|
|
227
|
+
* @returns Promise that resolves when the key is removed
|
|
228
|
+
*/
|
|
229
|
+
protected async clear(key: string): Promise<void> {
|
|
230
|
+
return this.tools.store.clear(key);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Removes all keys from this tool's storage.
|
|
235
|
+
*
|
|
236
|
+
* @returns Promise that resolves when all keys are removed
|
|
237
|
+
*/
|
|
238
|
+
protected async clearAll(): Promise<void> {
|
|
239
|
+
return this.tools.store.clearAll();
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Queues a callback to execute in a separate worker context with a fresh request limit.
|
|
244
|
+
*
|
|
245
|
+
* **Creates a NEW execution** with its own request limit of ~1000 requests (HTTP requests,
|
|
246
|
+
* tool calls, database operations). This is the primary way to stay under request limits
|
|
247
|
+
* when processing large datasets or making many API calls.
|
|
248
|
+
*
|
|
249
|
+
* Use this to break long loops into chunks that each stay under the ~1000 request limit.
|
|
250
|
+
* Each task runs in an isolated execution environment with ~1000 requests and ~60 seconds CPU time.
|
|
251
|
+
*
|
|
252
|
+
* @param callback - The callback token created with `this.callback()`
|
|
253
|
+
* @param options - Optional configuration for the execution
|
|
254
|
+
* @param options.runAt - If provided, schedules execution at this time; otherwise runs immediately
|
|
255
|
+
* @returns Promise resolving to a cancellation token (only for scheduled executions)
|
|
256
|
+
*
|
|
257
|
+
* @example
|
|
258
|
+
* ```typescript
|
|
259
|
+
* // Break large loop into batches
|
|
260
|
+
* const callback = await this.callback("processBatch", { page: 1 });
|
|
261
|
+
* await this.runTask(callback); // New execution with fresh request limit
|
|
262
|
+
* ```
|
|
263
|
+
*/
|
|
264
|
+
protected async runTask(
|
|
265
|
+
callback: Callback,
|
|
266
|
+
options?: { runAt?: Date }
|
|
267
|
+
): Promise<string | void> {
|
|
268
|
+
return this.tools.tasks.runTask(callback, options);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Cancels a previously scheduled execution.
|
|
273
|
+
*
|
|
274
|
+
* @param token - The cancellation token returned by runTask() with runAt option
|
|
275
|
+
* @returns Promise that resolves when the cancellation is processed
|
|
276
|
+
*/
|
|
277
|
+
protected async cancelTask(token: string): Promise<void> {
|
|
278
|
+
return this.tools.tasks.cancelTask(token);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Cancels all scheduled executions for this tool.
|
|
283
|
+
*
|
|
284
|
+
* @returns Promise that resolves when all cancellations are processed
|
|
285
|
+
*/
|
|
286
|
+
protected async cancelAllTasks(): Promise<void> {
|
|
287
|
+
return this.tools.tasks.cancelAllTasks();
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Called before the twist's activate method, starting from the deepest tool dependencies.
|
|
292
|
+
*
|
|
293
|
+
* This method is called in a depth-first manner, with the deepest dependencies
|
|
294
|
+
* being called first, bubbling up to the top-level tools before the twist's
|
|
295
|
+
* activate method is called.
|
|
296
|
+
*
|
|
297
|
+
* @param context - Optional context containing the actor who triggered activation
|
|
298
|
+
* @returns Promise that resolves when pre-activation is complete
|
|
299
|
+
*/
|
|
300
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
301
|
+
preActivate(context?: { actor: Actor }): Promise<void> {
|
|
302
|
+
return Promise.resolve();
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Called after the twist's activate method, starting from the top-level tools.
|
|
307
|
+
*
|
|
308
|
+
* This method is called in reverse order, with top-level tools being called
|
|
309
|
+
* first, then cascading down to the deepest dependencies.
|
|
310
|
+
*
|
|
311
|
+
* @param context - Optional context containing the actor who triggered activation
|
|
312
|
+
* @returns Promise that resolves when post-activation is complete
|
|
313
|
+
*/
|
|
314
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
315
|
+
postActivate(context?: { actor: Actor }): Promise<void> {
|
|
316
|
+
return Promise.resolve();
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Called before the twist's upgrade method, starting from the deepest tool dependencies.
|
|
321
|
+
*
|
|
322
|
+
* This method is called in a depth-first manner, with the deepest dependencies
|
|
323
|
+
* being called first, bubbling up to the top-level tools before the twist's
|
|
324
|
+
* upgrade method is called.
|
|
325
|
+
*
|
|
326
|
+
* @returns Promise that resolves when pre-upgrade is complete
|
|
327
|
+
*/
|
|
328
|
+
preUpgrade(): Promise<void> {
|
|
329
|
+
return Promise.resolve();
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Called after the twist's upgrade method, starting from the top-level tools.
|
|
334
|
+
*
|
|
335
|
+
* This method is called in reverse order, with top-level tools being called
|
|
336
|
+
* first, then cascading down to the deepest dependencies.
|
|
337
|
+
*
|
|
338
|
+
* @returns Promise that resolves when post-upgrade is complete
|
|
339
|
+
*/
|
|
340
|
+
postUpgrade(): Promise<void> {
|
|
341
|
+
return Promise.resolve();
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Called before the twist's deactivate method, starting from the deepest tool dependencies.
|
|
346
|
+
*
|
|
347
|
+
* This method is called in a depth-first manner, with the deepest dependencies
|
|
348
|
+
* being called first, bubbling up to the top-level tools before the twist's
|
|
349
|
+
* deactivate method is called.
|
|
350
|
+
*
|
|
351
|
+
* @returns Promise that resolves when pre-deactivation is complete
|
|
352
|
+
*/
|
|
353
|
+
preDeactivate(): Promise<void> {
|
|
354
|
+
return Promise.resolve();
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Called after the twist's deactivate method, starting from the top-level tools.
|
|
359
|
+
*
|
|
360
|
+
* This method is called in reverse order, with top-level tools being called
|
|
361
|
+
* first, then cascading down to the deepest dependencies.
|
|
362
|
+
*
|
|
363
|
+
* @returns Promise that resolves when post-deactivation is complete
|
|
364
|
+
*/
|
|
365
|
+
postDeactivate(): Promise<void> {
|
|
366
|
+
return Promise.resolve();
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Waits for tool initialization to complete.
|
|
371
|
+
* Called automatically by the entrypoint before lifecycle methods.
|
|
372
|
+
* @internal
|
|
373
|
+
*/
|
|
374
|
+
async waitForReady(): Promise<void> {
|
|
375
|
+
await this.toolShed.waitForReady();
|
|
376
|
+
}
|
|
377
|
+
}
|