Skip to content

Commit 34a227f

Browse files
authored
Merge pull request #51 from plotday/feat/permissions
Agent and tool permissions
2 parents ade731f + b3242e4 commit 34a227f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1869
-1387
lines changed

.changeset/full-queens-ask.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@plotday/tool-outlook-calendar": minor
3+
"@plotday/tool-google-calendar": minor
4+
"@plotday/tool-google-contacts": minor
5+
"@plotday/sdk": minor
6+
---
7+
8+
Changed: BREAKING: Creating and updating Activity using the Plot tool now requires requesting permission in options

.changeset/fuzzy-beans-thank.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
"@plotday/tool-outlook-calendar": minor
3+
"@plotday/tool-google-calendar": minor
4+
"@plotday/tool-google-contacts": minor
5+
"@plotday/sdk": minor
6+
---
7+
8+
Changed: BREAKING: Agents and Tools now define a build() method to gain access to tools, which are then available via this.tools.
9+
Changed: BREAKING: Webhook functionality has been moved into the Network tool.
10+
Changed: BREAKING: CallbackTool renamed Callbacks.
11+
Changed: BREAKING: Auth renamed Integrations.
12+
Changed: BREAKING: Run renamed Tasks.

.changeset/lazy-snakes-refuse.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@plotday/sdk": minor
3+
---
4+
5+
Added: Improved stack traces

.changeset/sparkly-candles-camp.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@plotday/tool-outlook-calendar": patch
3+
"@plotday/tool-google-calendar": patch
4+
"@plotday/tool-google-contacts": patch
5+
---
6+
7+
Changed: Update for new callback function names

.changeset/sweet-clouds-dance.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@plotday/sdk": minor
3+
---
4+
5+
Changed: BREAKING: Renamed callCallback, run, cancel, and cancelAll Agent/Tool functions

.changeset/warm-beds-jump.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@plotday/tool-outlook-calendar": minor
3+
"@plotday/tool-google-calendar": minor
4+
"@plotday/tool-google-contacts": minor
5+
"@plotday/sdk": minor
6+
---
7+
8+
Changed: BREAKING: Improved callback ergonomics and types to use functions instead of strings

agents/chat/src/index.ts

Lines changed: 95 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -6,129 +6,118 @@ import {
66
Agent,
77
AuthorType,
88
Tag,
9-
type Tools,
9+
type ToolBuilder,
1010
} from "@plotday/sdk";
1111
import { AI, type AIMessage } from "@plotday/sdk/tools/ai";
12-
import { Plot } from "@plotday/sdk/tools/plot";
12+
import { ActivityAccess, Plot } from "@plotday/sdk/tools/plot";
1313

14-
export default class extends Agent {
15-
private ai: AI;
16-
private plot: Plot;
17-
18-
constructor(id: string, protected tools: Tools) {
19-
super(id, tools);
20-
this.ai = tools.get(AI);
21-
this.plot = tools.get(Plot);
14+
export default class ChatAgent extends Agent<ChatAgent> {
15+
build(build: ToolBuilder) {
16+
return {
17+
ai: build(AI),
18+
plot: build(Plot, {
19+
activity: {
20+
access: ActivityAccess.Respond,
21+
intents: {
22+
"Respond to general questions and requests": this.responsd,
23+
},
24+
},
25+
}),
26+
};
2227
}
2328

24-
async activity(
25-
activity: Activity,
26-
changes?: {
27-
previous: Activity;
28-
tagsAdded: Record<number, string[]>;
29-
tagsRemoved: Record<number, string[]>;
30-
}
31-
) {
32-
if (changes) return;
33-
34-
const previousActivities = await this.plot.getThread(activity);
29+
async responsd(activity: Activity) {
30+
const previousActivities = await this.tools.plot.getThread(activity);
3531

36-
if (
37-
activity.note?.includes("@chat") ||
38-
previousActivities.some((activity: any) =>
39-
activity.note.includes("@chat")
40-
)
41-
) {
42-
// Add Thinking tag to indicate processing has started
43-
await this.plot.updateActivity({
44-
id: activity.id,
45-
tags: {
46-
[Tag.Agent]: true,
47-
},
48-
});
32+
// Add Thinking tag to indicate processing has started
33+
await this.tools.plot.updateActivity({
34+
id: activity.id,
35+
tags: {
36+
[Tag.Agent]: true,
37+
},
38+
});
4939

50-
const messages: AIMessage[] = [
51-
{
52-
role: "system",
53-
content: `You are an AI assistant inside of a productivity app.
40+
const messages: AIMessage[] = [
41+
{
42+
role: "system",
43+
content: `You are an AI assistant inside of a productivity app.
5444
You respond helpfully to user requests.
5545
You can also create tasks, but should only do so when the user explicitly asks you to.`,
56-
},
57-
...previousActivities
58-
.filter((a) => a.note ?? a.title)
59-
.map(
60-
(prevActivity) =>
61-
({
62-
role:
63-
prevActivity.author.type === AuthorType.Agent
64-
? "assistant"
65-
: "user",
66-
content: (prevActivity.note ?? prevActivity.title)!,
67-
} satisfies AIMessage)
68-
),
69-
];
46+
},
47+
...previousActivities
48+
.filter((a) => a.note ?? a.title)
49+
.map(
50+
(prevActivity) =>
51+
({
52+
role:
53+
prevActivity.author.type === AuthorType.Agent
54+
? "assistant"
55+
: "user",
56+
content: (prevActivity.note ?? prevActivity.title)!,
57+
} satisfies AIMessage)
58+
),
59+
];
7060

71-
const schema = Type.Object({
72-
message: Type.Object({
73-
note: Type.String({ description: "Response to the user's prompt" }),
74-
title: Type.String({
75-
description: "Short title for the response notee",
76-
}),
61+
const schema = Type.Object({
62+
message: Type.Object({
63+
note: Type.String({ description: "Response to the user's prompt" }),
64+
title: Type.String({
65+
description: "Short title for the response notee",
7766
}),
78-
action_items: Type.Optional(
79-
Type.Array(
80-
Type.Object({
81-
note: Type.Optional(
82-
Type.String({
83-
description:
84-
"Optional detailed description of the action item. Can include markdown. Only add when important details are needed beyond the title.",
85-
})
86-
),
87-
title: Type.String({
67+
}),
68+
action_items: Type.Optional(
69+
Type.Array(
70+
Type.Object({
71+
note: Type.Optional(
72+
Type.String({
8873
description:
89-
"Succinct description of the action item (no markdown)",
90-
}),
74+
"Optional detailed description of the action item. Can include markdown. Only add when important details are needed beyond the title.",
75+
})
76+
),
77+
title: Type.String({
78+
description:
79+
"Succinct description of the action item (no markdown)",
9180
}),
92-
{
93-
description: "Tasks to create in response to the user's request.",
94-
}
95-
)
96-
),
97-
});
81+
}),
82+
{
83+
description: "Tasks to create in response to the user's request.",
84+
}
85+
)
86+
),
87+
});
9888

99-
const response = await this.ai.prompt({
100-
model: { speed: "balanced", cost: "low" },
101-
messages,
102-
outputSchema: schema,
103-
});
89+
const response = await this.tools.ai.prompt({
90+
model: { speed: "balanced", cost: "low" },
91+
messages,
92+
outputSchema: schema,
93+
});
10494

105-
await Promise.all([
106-
this.plot.createActivity({
107-
title: response.output!.message.title,
108-
note: response.output!.message.note,
95+
await Promise.all([
96+
this.tools.plot.createActivity({
97+
title: response.output!.message.title,
98+
note: response.output!.message.note,
99+
parent: activity,
100+
priority: activity.priority,
101+
type: activity.type,
102+
}),
103+
...(response.output!.action_items?.map((item: any) =>
104+
this.tools.plot.createActivity({
105+
title: item.title,
106+
note: item.note,
109107
parent: activity,
110108
priority: activity.priority,
111-
type: activity.type,
112-
}),
113-
...(response.output!.action_items?.map((item: any) =>
114-
this.plot.createActivity({
115-
title: item.title,
116-
note: item.note,
117-
parent: activity,
118-
priority: activity.priority,
119-
type: ActivityType.Task,
120-
start: new Date(),
121-
})
122-
) ?? []),
123-
]);
109+
type: ActivityType.Task,
110+
start: new Date(),
111+
})
112+
) ?? []),
113+
]);
124114

125-
// Remove Thinking tag after response is created
126-
await this.plot.updateActivity({
127-
id: activity.id,
128-
tags: {
129-
[Tag.Agent]: false,
130-
},
131-
});
132-
}
115+
// Remove Thinking tag after response is created
116+
await this.tools.plot.updateActivity({
117+
id: activity.id,
118+
tags: {
119+
[Tag.Agent]: false,
120+
},
121+
});
133122
}
134123
}

0 commit comments

Comments
 (0)