You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
content: "Your twist is ready to use. Check out the [documentation](https://twist.plot.day) to learn more.",
85
+
},
86
+
],
82
87
});
83
88
}
84
89
}
@@ -124,22 +129,38 @@ Twist tools provide capabilities to twists. They are usually unopinionated and d
124
129
125
130
[View all tools →](https://twist.plot.day/documents/Built-in_Tools.html)
126
131
127
-
### Activities
132
+
### Activities and Notes
128
133
129
-
The core data type representing tasks, events, and notes.
134
+
**Activity** represents something done or to be done (a task, event, or conversation).
135
+
**Notes** represent updates and details on that activity.
136
+
137
+
Think of an **Activity as a thread** and **Notes as messages in that thread**. Always create activities with an initial note, and add notes for updates rather than creating new activities.
130
138
131
139
```typescript
140
+
// Create an activity with an initial note (thread with first message)
132
141
awaitthis.tools.plot.createActivity({
133
142
type: ActivityType.Action,
134
143
title: "Review pull request",
135
-
links: [
144
+
source: "github:pr:123", // For deduplication
145
+
notes: [
136
146
{
137
-
type: ActivityLinkType.external,
138
-
title: "View PR",
139
-
url: "https://github.com/org/repo/pull/123",
147
+
content: "New PR ready for review",
148
+
links: [
149
+
{
150
+
type: ActivityLinkType.external,
151
+
title: "View PR",
152
+
url: "https://github.com/org/repo/pull/123",
153
+
},
154
+
],
140
155
},
141
156
],
142
157
});
158
+
159
+
// Add a note to existing activity (add message to thread)
160
+
awaitthis.tools.plot.createNote({
161
+
activity: { id: activityId },
162
+
content: "LGTM! Approved ✅",
163
+
});
143
164
```
144
165
145
166
[Learn more →](https://twist.plot.day/documents/Core_Concepts.html)
@@ -17,14 +17,39 @@ Plot Twists are TypeScript classes that extend the `Twist` base class. Twists in
17
17
-**Store intermediate state**: Use the Store tool to persist state between batches
18
18
-**Examples**: Syncing large datasets, processing many API calls, or performing batch operations
19
19
20
-
## twist Structure Pattern
20
+
## Understanding Activities and Notes
21
+
22
+
**CRITICAL CONCEPT**: An **Activity** represents something done or to be done (a task, event, or conversation), while **Notes** represent the updates and details on that activity.
23
+
24
+
**Think of an Activity as a thread** on a messaging platform, and **Notes as the messages in that thread**.
25
+
26
+
### Key Guidelines
27
+
28
+
1.**Always create Activities with an initial Note** - The title is just a summary; detailed content goes in Notes
29
+
2.**Add Notes to existing Activities for updates** - Don't create a new Activity for each related message
30
+
3.**Use `source` field for deduplication** - Enables safe, idempotent sync from external systems
31
+
4.**Most Activities should be `ActivityType.Note`** - Use `Action` only for tasks with `doneAt`, use `Event` only for items with `start`/`end`
32
+
33
+
### Decision Tree
34
+
35
+
```
36
+
New event/task/conversation?
37
+
├─ Yes → Create new Activity with initial Note
38
+
│ Include `source` field for deduplication
39
+
│
40
+
└─ No (update/reply/comment) → Check for existing Activity
41
+
├─ Found → Add Note to existing Activity
42
+
└─ Not found → Create new Activity with initial Note
note: `Failed to complete operation: ${error.message}`,
459
+
title: "Operation failed",
460
+
notes: [
461
+
{
462
+
content: `Failed to complete operation: ${error.message}`,
463
+
},
464
+
],
379
465
});
380
466
}
381
467
```
@@ -384,7 +470,10 @@ try {
384
470
385
471
-**Don't use instance variables for state** - Anything stored in memory is lost after function execution. Always use the Store tool for data that needs to persist.
386
472
-**Processing self-created activities** - Other users may change an Activity created by the twist, resulting in an \`activity\` call. Be sure to check the \`changes === null\` and/or \`activity.author.id !== this.id\` to avoid re-processing.
387
-
- Most activity should be `type = ActivityType.Note` with a `title` and `note`, and no `start` or `end`. This represents a typical message. `start` and `end` should only be used for a note if it should be displayed for a specific date or time, such as a birthday.
473
+
-**Always create Activities with Notes** - See "Understanding Activities and Notes" section above for the thread/message pattern and decision tree.
474
+
-**Use correct Activity types** - Most should be `ActivityType.Note`. Only use `Action` for tasks with `doneAt`, and `Event` for items with `start`/`end`.
475
+
-**Use `source` field for deduplication** - Always include `source` when syncing external data to enable safe, idempotent operations.
476
+
-**Add Notes to existing Activities** - Check for existing Activities with `getActivityBySource()` before creating new ones. Think thread replies, not new threads.
388
477
- Tools are declared in the `build` method and accessed via `this.tools.toolName` in twist methods.
389
478
-**Don't forget runtime limits** - Each execution has ~10 seconds. Break long operations into batches with the Tasks tool. Process enough items per batch to be efficient, but few enough to stay under time limits.
390
479
-**Always use Callbacks tool for persistent references** - Direct function references don't survive worker restarts.
0 commit comments