Skip to content

Commit cdb2eac

Browse files
committed
feat: add guides tool
1 parent a739e40 commit cdb2eac

File tree

3 files changed

+226
-0
lines changed

3 files changed

+226
-0
lines changed

.changeset/upset-cameras-guess.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@knocklabs/agent-toolkit": minor
3+
---
4+
5+
feat: add tool for interacting with Knock guides

src/lib/tools/guides.ts

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
import { z } from "zod";
2+
3+
import { KnockTool } from "../knock-tool.js";
4+
5+
/**
6+
* A slimmed down version of the Guide resource that is easier to work with in the LLM.
7+
*/
8+
type SerializedGuide = {
9+
key: string;
10+
name: string;
11+
description?: string;
12+
type: string;
13+
active: boolean;
14+
};
15+
16+
function serializeGuide(guide: any): SerializedGuide {
17+
return {
18+
key: guide.key,
19+
name: guide.name,
20+
description: guide.description,
21+
type: guide.type,
22+
active: guide.active,
23+
};
24+
}
25+
26+
const listGuides = KnockTool({
27+
method: "list_guides",
28+
name: "List guides",
29+
description: `
30+
List all guides available for the given environment. Returns structural information about the guides, including the key, name, description, type, and status.
31+
32+
Use this tool when you need to understand which guides are available in the environment.
33+
`,
34+
parameters: z.object({
35+
environment: z
36+
.string()
37+
.optional()
38+
.describe(
39+
"(string): The environment to list guides for. Defaults to `development`."
40+
),
41+
page_size: z
42+
.number()
43+
.optional()
44+
.describe("(number): The number of guides to return per page."),
45+
after: z
46+
.string()
47+
.optional()
48+
.describe("(string): The cursor to use for pagination."),
49+
}),
50+
execute: (_knockClient, _config) => async (_params) => {
51+
// TODO: Replace with actual guides API when published
52+
// const allGuides: SerializedGuide[] = [];
53+
// const listParams = {
54+
// environment: params.environment ?? config.environment ?? "development",
55+
// page_size: params.page_size,
56+
// after: params.after,
57+
// };
58+
// for await (const guide of knockClient.guides.list(listParams)) {
59+
// allGuides.push(serializeGuide(guide));
60+
// }
61+
// return allGuides;
62+
63+
// Placeholder implementation until guides API is published
64+
throw new Error(
65+
"Guides API is not yet available in the Knock management SDK"
66+
);
67+
},
68+
});
69+
70+
const getGuide = KnockTool({
71+
method: "get_guide",
72+
name: "Get guide",
73+
description: `
74+
Get a guide by its key. Returns structural information about the guide, including the key, name, description, type, and status.
75+
76+
Use this tool when you need to retrieve information about a specific guide.
77+
`,
78+
parameters: z.object({
79+
environment: z
80+
.string()
81+
.optional()
82+
.describe(
83+
"(string): The environment to get the guide for. Defaults to `development`."
84+
),
85+
guideKey: z.string().describe("(string): The key of the guide to get."),
86+
hide_uncommitted_changes: z
87+
.boolean()
88+
.optional()
89+
.describe(
90+
"(boolean): Whether to hide uncommitted changes and return only published version."
91+
),
92+
}),
93+
execute: (_knockClient, _config) => async (_params) => {
94+
// TODO: Replace with actual guides API when published
95+
// const guide = await knockClient.guides.retrieve(params.guideKey, {
96+
// environment: params.environment ?? config.environment ?? "development",
97+
// hide_uncommitted_changes: params.hide_uncommitted_changes,
98+
// });
99+
// return serializeGuide(guide);
100+
101+
// Placeholder implementation until guides API is published
102+
throw new Error(
103+
"Guides API is not yet available in the Knock management SDK"
104+
);
105+
},
106+
});
107+
108+
const createOrUpdateGuide = KnockTool({
109+
method: "upsert_guide",
110+
name: "Upsert guide",
111+
description: `
112+
Create or update a guide. A guide defines an in-app guide that can be displayed to users based on priority and other conditions.
113+
114+
Use this tool when you need to create a new guide or update an existing one. The guide will be created with the specified configuration.
115+
116+
Note: This endpoint only operates on guides in the "development" environment.
117+
`,
118+
parameters: z.object({
119+
environment: z
120+
.string()
121+
.optional()
122+
.describe(
123+
"(string): The environment to upsert the guide for. Defaults to `development`."
124+
),
125+
guideKey: z
126+
.string()
127+
.describe(
128+
"(string): The key of the guide to upsert. Must be at minimum 3 characters and at maximum 255 characters in length. Must be in the format of ^[a-z0-9_-]+$."
129+
),
130+
guide: z
131+
.object({
132+
name: z
133+
.string()
134+
.describe(
135+
"(string): A name for the guide. Must be at maximum 255 characters in length."
136+
),
137+
description: z
138+
.string()
139+
.optional()
140+
.describe(
141+
"(string): An arbitrary string attached to a guide object. Maximum of 280 characters allowed."
142+
),
143+
priority: z
144+
.number()
145+
.min(1)
146+
.max(9999)
147+
.describe(
148+
"(number): The priority of the guide. Must be between 1 and 9999."
149+
),
150+
channel_key: z
151+
.string()
152+
.describe(
153+
"(string): The key of the channel in which the guide exists."
154+
),
155+
type: z.string().describe("(string): The type of the guide."),
156+
semver: z.string().describe("(string): The semver of the guide."),
157+
steps: z
158+
.array(z.any())
159+
.describe("(array): A list of guide step objects in the guide."),
160+
target_audience_id: z
161+
.string()
162+
.optional()
163+
.describe("(string): The ID of the target audience for the guide."),
164+
target_property_conditions: z
165+
.any()
166+
.optional()
167+
.describe(
168+
"(object): A conditions object that describes one or more conditions to be met for the guide to be shown to an audience member."
169+
),
170+
activation_location_rules: z
171+
.array(z.any())
172+
.describe(
173+
"(array): A list of activation location rules that describe when the guide should be shown."
174+
),
175+
})
176+
.describe("(object): The guide configuration to upsert."),
177+
commit: z
178+
.boolean()
179+
.optional()
180+
.describe("(boolean): Whether to commit the changes immediately."),
181+
commit_message: z
182+
.string()
183+
.optional()
184+
.describe("(string): The commit message when committing changes."),
185+
annotate: z
186+
.boolean()
187+
.optional()
188+
.describe("(boolean): Whether to annotate the changes."),
189+
}),
190+
execute: (_knockClient, _config) => async (_params) => {
191+
// TODO: Replace with actual guides API when published
192+
// const result = await knockClient.guides.upsert(params.guideKey, {
193+
// environment: params.environment ?? config.environment ?? "development",
194+
// guide: params.guide,
195+
// commit: params.commit,
196+
// commit_message: params.commit_message,
197+
// annotate: params.annotate,
198+
// });
199+
// return serializeGuide(result.guide);
200+
201+
// Placeholder implementation until guides API is published
202+
throw new Error(
203+
"Guides API is not yet available in the Knock management SDK"
204+
);
205+
},
206+
});
207+
208+
export const guides = {
209+
listGuides,
210+
getGuide,
211+
createOrUpdateGuide,
212+
};
213+
214+
export const permissions = {
215+
read: ["listGuides", "getGuide"],
216+
manage: ["createOrUpdateGuide"],
217+
};

src/lib/tools/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
environments,
1313
permissions as environmentsPermissions,
1414
} from "./environments.js";
15+
import { guides, permissions as guidesPermissions } from "./guides.js";
1516
import {
1617
messageTypes,
1718
permissions as messageTypesPermissions,
@@ -29,6 +30,7 @@ export const tools = {
2930
documentation,
3031
emailLayouts,
3132
environments,
33+
guides,
3234
messages,
3335
messageTypes,
3436
objects,
@@ -44,6 +46,7 @@ export const allTools = {
4446
...documentation,
4547
...emailLayouts,
4648
...environments,
49+
...guides,
4750
...messageTypes,
4851
...messages,
4952
...objects,
@@ -59,6 +62,7 @@ export const toolPermissions = {
5962
documentation: documentationPermissions,
6063
emailLayouts: emailLayoutsPermissions,
6164
environments: environmentsPermissions,
65+
guides: guidesPermissions,
6266
messages: messagesPermissions,
6367
messageTypes: messageTypesPermissions,
6468
objects: objectsPermissions,

0 commit comments

Comments
 (0)