@sentry/junior-plugin-api 0.89.0 → 0.90.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/dist/index.js CHANGED
@@ -196,82 +196,158 @@ var pluginRunContextSchema = z4.object({
196
196
  }).strict();
197
197
 
198
198
  // src/tools.ts
199
+ import { z as z5 } from "zod";
199
200
  var PluginToolInputError = class extends Error {
200
201
  constructor(message, options) {
201
202
  super(message, options);
202
203
  this.name = "PluginToolInputError";
203
204
  }
204
205
  };
206
+ var pluginToolContinuationSchema = z5.object({
207
+ arguments: z5.record(z5.string(), z5.unknown()),
208
+ reason: z5.string().min(1).optional()
209
+ }).strict();
210
+ var pluginToolErrorSchema = z5.object({
211
+ kind: z5.string().min(1),
212
+ message: z5.string().min(1),
213
+ retryable: z5.boolean().optional()
214
+ }).strict();
215
+ var pluginToolResultSchema = z5.object({
216
+ ok: z5.boolean(),
217
+ status: z5.enum(["success", "error"]),
218
+ target: z5.string().min(1).optional(),
219
+ data: z5.unknown().optional(),
220
+ truncated: z5.boolean().optional(),
221
+ continuation: pluginToolContinuationSchema.optional(),
222
+ error: z5.union([pluginToolErrorSchema, z5.string()]).optional()
223
+ }).passthrough();
224
+ function formatZodPath(path) {
225
+ return path.length > 0 ? path.map(String).join(".") : "root";
226
+ }
227
+ function formatPluginToolInputError(error) {
228
+ const details = error.issues.slice(0, 5).map((issue) => `${formatZodPath(issue.path)}: ${issue.message}`).join("; ");
229
+ return `Invalid tool arguments: ${details || "input did not match schema"}`;
230
+ }
231
+ function parsePluginToolInput(schema, args) {
232
+ const result = schema.safeParse(args);
233
+ if (!result.success) {
234
+ throw new PluginToolInputError(formatPluginToolInputError(result.error), {
235
+ cause: result.error
236
+ });
237
+ }
238
+ return result.data;
239
+ }
240
+ function definePluginTool(definition) {
241
+ const { inputSchema, outputSchema, prepareArguments, execute, ...tool } = definition;
242
+ let modelInputSchema;
243
+ let modelOutputSchema;
244
+ try {
245
+ modelInputSchema = z5.toJSONSchema(inputSchema);
246
+ } catch (error) {
247
+ throw new TypeError(
248
+ "definePluginTool() inputSchema must be representable as JSON Schema.",
249
+ { cause: error }
250
+ );
251
+ }
252
+ try {
253
+ modelOutputSchema = z5.toJSONSchema(outputSchema);
254
+ } catch (error) {
255
+ throw new TypeError(
256
+ "definePluginTool() outputSchema must be representable as JSON Schema.",
257
+ { cause: error }
258
+ );
259
+ }
260
+ return {
261
+ ...tool,
262
+ inputSchema: modelInputSchema,
263
+ outputSchema: modelOutputSchema,
264
+ prepareArguments(args) {
265
+ return parsePluginToolInput(
266
+ inputSchema,
267
+ prepareArguments ? prepareArguments(args) : args
268
+ );
269
+ },
270
+ ...execute ? {
271
+ async execute(input, options) {
272
+ const result = await execute(
273
+ input,
274
+ options
275
+ );
276
+ return outputSchema.parse(pluginToolResultSchema.parse(result));
277
+ }
278
+ } : {}
279
+ };
280
+ }
205
281
 
206
282
  // src/operations.ts
207
- import { z as z5 } from "zod";
208
- var pluginApiRouteRequestContextSchema = z5.object({
209
- auth: z5.object({
210
- user: z5.object({
211
- email: z5.string().nullable().optional(),
212
- emailVerified: z5.boolean().optional(),
213
- hostedDomain: z5.string().nullable().optional(),
214
- name: z5.string().nullable().optional()
283
+ import { z as z6 } from "zod";
284
+ var pluginApiRouteRequestContextSchema = z6.object({
285
+ auth: z6.object({
286
+ user: z6.object({
287
+ email: z6.string().nullable().optional(),
288
+ emailVerified: z6.boolean().optional(),
289
+ hostedDomain: z6.string().nullable().optional(),
290
+ name: z6.string().nullable().optional()
215
291
  }).strict()
216
292
  }).strict(),
217
293
  pluginName: nonBlankStringSchema
218
294
  }).strict();
219
295
 
220
296
  // src/credentials.ts
221
- import { z as z6 } from "zod";
222
- var pluginProviderNameSchema = z6.string().regex(/^[a-z][a-z0-9-]*$/);
223
- var pluginGrantNameSchema = z6.string().regex(/^[a-z][a-z0-9.-]*$/);
224
- var pluginGrantAccessSchema = z6.union([
225
- z6.literal("read"),
226
- z6.literal("write")
297
+ import { z as z7 } from "zod";
298
+ var pluginProviderNameSchema = z7.string().regex(/^[a-z][a-z0-9-]*$/);
299
+ var pluginGrantNameSchema = z7.string().regex(/^[a-z][a-z0-9.-]*$/);
300
+ var pluginGrantAccessSchema = z7.union([
301
+ z7.literal("read"),
302
+ z7.literal("write")
227
303
  ]);
228
- var pluginAuthorizationSchema = z6.object({
304
+ var pluginAuthorizationSchema = z7.object({
229
305
  provider: pluginProviderNameSchema,
230
306
  scope: nonBlankStringSchema.optional(),
231
- type: z6.literal("oauth")
307
+ type: z7.literal("oauth")
232
308
  }).strict();
233
- var pluginProviderAccountSchema = z6.object({
309
+ var pluginProviderAccountSchema = z7.object({
234
310
  id: nonBlankStringSchema,
235
311
  label: nonBlankStringSchema.optional(),
236
312
  url: nonBlankStringSchema.optional()
237
313
  }).strict();
238
- var pluginStoredTokensSchema = z6.object({
314
+ var pluginStoredTokensSchema = z7.object({
239
315
  account: pluginProviderAccountSchema.optional(),
240
316
  accessToken: nonBlankStringSchema,
241
- expiresAt: z6.number().finite().optional(),
317
+ expiresAt: z7.number().finite().optional(),
242
318
  refreshToken: nonBlankStringSchema,
243
- refreshTokenExpiresAt: z6.number().finite().optional(),
319
+ refreshTokenExpiresAt: z7.number().finite().optional(),
244
320
  scope: nonBlankStringSchema.optional()
245
321
  }).strict();
246
- var pluginGrantSchema = z6.object({
322
+ var pluginGrantSchema = z7.object({
247
323
  access: pluginGrantAccessSchema,
248
324
  name: pluginGrantNameSchema,
249
325
  reason: nonBlankStringSchema.optional(),
250
- requirements: z6.array(nonBlankStringSchema).min(1).optional()
326
+ requirements: z7.array(nonBlankStringSchema).min(1).optional()
251
327
  }).strict();
252
- var pluginCredentialHeaderTransformSchema = z6.object({
253
- domain: z6.string().min(1),
254
- headers: z6.record(z6.string(), z6.string()).refine((headers) => Object.keys(headers).length > 0)
328
+ var pluginCredentialHeaderTransformSchema = z7.object({
329
+ domain: z7.string().min(1),
330
+ headers: z7.record(z7.string(), z7.string()).refine((headers) => Object.keys(headers).length > 0)
255
331
  }).strict();
256
- var pluginCredentialLeaseSchema = z6.object({
332
+ var pluginCredentialLeaseSchema = z7.object({
257
333
  account: pluginProviderAccountSchema.optional(),
258
334
  authorization: pluginAuthorizationSchema.optional(),
259
- expiresAt: z6.string().refine((value) => Number.isFinite(Date.parse(value))),
260
- headerTransforms: z6.array(pluginCredentialHeaderTransformSchema).min(1)
335
+ expiresAt: z7.string().refine((value) => Number.isFinite(Date.parse(value))),
336
+ headerTransforms: z7.array(pluginCredentialHeaderTransformSchema).min(1)
261
337
  }).strict();
262
- var pluginCredentialResultSchema = z6.discriminatedUnion("type", [
263
- z6.object({
338
+ var pluginCredentialResultSchema = z7.discriminatedUnion("type", [
339
+ z7.object({
264
340
  lease: pluginCredentialLeaseSchema,
265
- type: z6.literal("lease")
341
+ type: z7.literal("lease")
266
342
  }).strict(),
267
- z6.object({
343
+ z7.object({
268
344
  authorization: pluginAuthorizationSchema.optional(),
269
345
  message: nonBlankStringSchema,
270
- type: z6.literal("needed")
346
+ type: z7.literal("needed")
271
347
  }).strict(),
272
- z6.object({
348
+ z7.object({
273
349
  message: nonBlankStringSchema,
274
- type: z6.literal("unavailable")
350
+ type: z7.literal("unavailable")
275
351
  }).strict()
276
352
  ]);
277
353
  var EgressAuthRequired = class extends Error {
@@ -336,6 +412,7 @@ export {
336
412
  createLocalSource,
337
413
  createSlackSource,
338
414
  defineJuniorPlugin,
415
+ definePluginTool,
339
416
  destinationSchema,
340
417
  dispatchOptionsSchema,
341
418
  getSourceKey,
@@ -357,6 +434,9 @@ export {
357
434
  pluginRunContextSchema,
358
435
  pluginRunTranscriptEntrySchema,
359
436
  pluginStoredTokensSchema,
437
+ pluginToolContinuationSchema,
438
+ pluginToolErrorSchema,
439
+ pluginToolResultSchema,
360
440
  promptMessageSchema,
361
441
  requesterSchema,
362
442
  slackDestinationSchema,
package/dist/tools.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { PluginContext, LocalInvocationContext, PluginEmbedder, PluginModel, Requester, SlackInvocationContext } from "./context";
2
2
  import type { PluginCredentialSubject } from "./credentials";
3
3
  import type { PluginState } from "./state";
4
+ import { z, type ZodType, type ZodTypeAny } from "zod";
4
5
  export interface PluginEnv {
5
6
  get(key: string): string | undefined;
6
7
  set(key: string, value: string): void;
@@ -72,14 +73,44 @@ export interface PluginToolExecuteOptions {
72
73
  /** Stable runtime tool-call id; durable create tools should derive idempotency keys from it. */
73
74
  toolCallId?: string;
74
75
  }
75
- export type PluginToolExecute<TInput = unknown> = {
76
- bivarianceHack(input: TInput, options: PluginToolExecuteOptions): Promise<unknown> | unknown;
76
+ export declare const pluginToolContinuationSchema: z.ZodObject<{
77
+ arguments: z.ZodRecord<z.ZodString, z.ZodUnknown>;
78
+ reason: z.ZodOptional<z.ZodString>;
79
+ }, z.core.$strict>;
80
+ export declare const pluginToolErrorSchema: z.ZodObject<{
81
+ kind: z.ZodString;
82
+ message: z.ZodString;
83
+ retryable: z.ZodOptional<z.ZodBoolean>;
84
+ }, z.core.$strict>;
85
+ export declare const pluginToolResultSchema: z.ZodObject<{
86
+ ok: z.ZodBoolean;
87
+ status: z.ZodEnum<{
88
+ error: "error";
89
+ success: "success";
90
+ }>;
91
+ target: z.ZodOptional<z.ZodString>;
92
+ data: z.ZodOptional<z.ZodUnknown>;
93
+ truncated: z.ZodOptional<z.ZodBoolean>;
94
+ continuation: z.ZodOptional<z.ZodObject<{
95
+ arguments: z.ZodRecord<z.ZodString, z.ZodUnknown>;
96
+ reason: z.ZodOptional<z.ZodString>;
97
+ }, z.core.$strict>>;
98
+ error: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
99
+ kind: z.ZodString;
100
+ message: z.ZodString;
101
+ retryable: z.ZodOptional<z.ZodBoolean>;
102
+ }, z.core.$strict>, z.ZodString]>>;
103
+ }, z.core.$loose>;
104
+ export type PluginToolResult = z.output<typeof pluginToolResultSchema>;
105
+ export type PluginToolExecute<TInput = unknown, TOutput = unknown> = {
106
+ bivarianceHack(input: TInput, options: PluginToolExecuteOptions): Promise<TOutput> | TOutput;
77
107
  }["bivarianceHack"];
78
- export interface PluginToolDefinition<TInput = unknown> {
108
+ export interface PluginToolDefinition<TInput = unknown, TOutput = unknown> {
79
109
  annotations?: unknown;
80
110
  description: string;
81
111
  executionMode?: unknown;
82
112
  inputSchema: unknown;
113
+ outputSchema?: unknown;
83
114
  prepareArguments?: (args: unknown) => unknown;
84
115
  /**
85
116
  * @deprecated Put tool-selection and usage guidance directly in `description`
@@ -93,8 +124,18 @@ export interface PluginToolDefinition<TInput = unknown> {
93
124
  * future major version.
94
125
  */
95
126
  promptSnippet?: string;
96
- execute?: PluginToolExecute<TInput>;
127
+ execute?: PluginToolExecute<TInput, TOutput>;
97
128
  }
129
+ type ZodPluginToolDefinition<TInputSchema extends ZodTypeAny, TOutputSchema extends ZodType<PluginToolResult>> = Omit<PluginToolDefinition<z.output<TInputSchema>, z.output<TOutputSchema>>, "inputSchema" | "outputSchema" | "prepareArguments" | "execute"> & {
130
+ inputSchema: TInputSchema;
131
+ outputSchema: TOutputSchema;
132
+ prepareArguments?: (args: unknown) => z.input<TInputSchema>;
133
+ execute?: (input: z.output<TInputSchema>, options: PluginToolExecuteOptions) => Promise<z.input<TOutputSchema>> | z.input<TOutputSchema>;
134
+ };
135
+ /**
136
+ * Define a plugin tool with Zod input parsing and the structured result contract.
137
+ */
138
+ export declare function definePluginTool<TInputSchema extends ZodTypeAny, TOutputSchema extends ZodType<PluginToolResult>>(definition: ZodPluginToolDefinition<TInputSchema, TOutputSchema>): PluginToolDefinition<z.output<TInputSchema>, z.output<TOutputSchema>>;
98
139
  export interface SlackToolRegistrationHookContext {
99
140
  /**
100
141
  * Capabilities of the source Slack conversation exposed to this plugin.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/junior-plugin-api",
3
- "version": "0.89.0",
3
+ "version": "0.90.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
package/src/tools.ts CHANGED
@@ -8,6 +8,7 @@ import type {
8
8
  } from "./context";
9
9
  import type { PluginCredentialSubject } from "./credentials";
10
10
  import type { PluginState } from "./state";
11
+ import { z, type ZodType, type ZodTypeAny } from "zod";
11
12
 
12
13
  export interface PluginEnv {
13
14
  get(key: string): string | undefined;
@@ -89,18 +90,48 @@ export interface PluginToolExecuteOptions {
89
90
  toolCallId?: string;
90
91
  }
91
92
 
92
- export type PluginToolExecute<TInput = unknown> = {
93
+ export const pluginToolContinuationSchema = z
94
+ .object({
95
+ arguments: z.record(z.string(), z.unknown()),
96
+ reason: z.string().min(1).optional(),
97
+ })
98
+ .strict();
99
+
100
+ export const pluginToolErrorSchema = z
101
+ .object({
102
+ kind: z.string().min(1),
103
+ message: z.string().min(1),
104
+ retryable: z.boolean().optional(),
105
+ })
106
+ .strict();
107
+
108
+ export const pluginToolResultSchema = z
109
+ .object({
110
+ ok: z.boolean(),
111
+ status: z.enum(["success", "error"]),
112
+ target: z.string().min(1).optional(),
113
+ data: z.unknown().optional(),
114
+ truncated: z.boolean().optional(),
115
+ continuation: pluginToolContinuationSchema.optional(),
116
+ error: z.union([pluginToolErrorSchema, z.string()]).optional(),
117
+ })
118
+ .passthrough();
119
+
120
+ export type PluginToolResult = z.output<typeof pluginToolResultSchema>;
121
+
122
+ export type PluginToolExecute<TInput = unknown, TOutput = unknown> = {
93
123
  bivarianceHack(
94
124
  input: TInput,
95
125
  options: PluginToolExecuteOptions,
96
- ): Promise<unknown> | unknown;
126
+ ): Promise<TOutput> | TOutput;
97
127
  }["bivarianceHack"];
98
128
 
99
- export interface PluginToolDefinition<TInput = unknown> {
129
+ export interface PluginToolDefinition<TInput = unknown, TOutput = unknown> {
100
130
  annotations?: unknown;
101
131
  description: string;
102
132
  executionMode?: unknown;
103
133
  inputSchema: unknown;
134
+ outputSchema?: unknown;
104
135
  prepareArguments?: (args: unknown) => unknown;
105
136
  /**
106
137
  * @deprecated Put tool-selection and usage guidance directly in `description`
@@ -114,7 +145,101 @@ export interface PluginToolDefinition<TInput = unknown> {
114
145
  * future major version.
115
146
  */
116
147
  promptSnippet?: string;
117
- execute?: PluginToolExecute<TInput>;
148
+ execute?: PluginToolExecute<TInput, TOutput>;
149
+ }
150
+
151
+ type ZodPluginToolDefinition<
152
+ TInputSchema extends ZodTypeAny,
153
+ TOutputSchema extends ZodType<PluginToolResult>,
154
+ > = Omit<
155
+ PluginToolDefinition<z.output<TInputSchema>, z.output<TOutputSchema>>,
156
+ "inputSchema" | "outputSchema" | "prepareArguments" | "execute"
157
+ > & {
158
+ inputSchema: TInputSchema;
159
+ outputSchema: TOutputSchema;
160
+ prepareArguments?: (args: unknown) => z.input<TInputSchema>;
161
+ execute?: (
162
+ input: z.output<TInputSchema>,
163
+ options: PluginToolExecuteOptions,
164
+ ) => Promise<z.input<TOutputSchema>> | z.input<TOutputSchema>;
165
+ };
166
+
167
+ function formatZodPath(path: readonly PropertyKey[]): string {
168
+ return path.length > 0 ? path.map(String).join(".") : "root";
169
+ }
170
+
171
+ function formatPluginToolInputError(error: z.ZodError): string {
172
+ const details = error.issues
173
+ .slice(0, 5)
174
+ .map((issue) => `${formatZodPath(issue.path)}: ${issue.message}`)
175
+ .join("; ");
176
+ return `Invalid tool arguments: ${details || "input did not match schema"}`;
177
+ }
178
+
179
+ function parsePluginToolInput<TInputSchema extends ZodTypeAny>(
180
+ schema: TInputSchema,
181
+ args: unknown,
182
+ ): z.output<TInputSchema> {
183
+ const result = schema.safeParse(args);
184
+ if (!result.success) {
185
+ throw new PluginToolInputError(formatPluginToolInputError(result.error), {
186
+ cause: result.error,
187
+ });
188
+ }
189
+ return result.data;
190
+ }
191
+
192
+ /**
193
+ * Define a plugin tool with Zod input parsing and the structured result contract.
194
+ */
195
+ export function definePluginTool<
196
+ TInputSchema extends ZodTypeAny,
197
+ TOutputSchema extends ZodType<PluginToolResult>,
198
+ >(
199
+ definition: ZodPluginToolDefinition<TInputSchema, TOutputSchema>,
200
+ ): PluginToolDefinition<z.output<TInputSchema>, z.output<TOutputSchema>> {
201
+ const { inputSchema, outputSchema, prepareArguments, execute, ...tool } =
202
+ definition;
203
+ let modelInputSchema: unknown;
204
+ let modelOutputSchema: unknown;
205
+ try {
206
+ modelInputSchema = z.toJSONSchema(inputSchema);
207
+ } catch (error) {
208
+ throw new TypeError(
209
+ "definePluginTool() inputSchema must be representable as JSON Schema.",
210
+ { cause: error },
211
+ );
212
+ }
213
+ try {
214
+ modelOutputSchema = z.toJSONSchema(outputSchema);
215
+ } catch (error) {
216
+ throw new TypeError(
217
+ "definePluginTool() outputSchema must be representable as JSON Schema.",
218
+ { cause: error },
219
+ );
220
+ }
221
+ return {
222
+ ...tool,
223
+ inputSchema: modelInputSchema,
224
+ outputSchema: modelOutputSchema,
225
+ prepareArguments(args) {
226
+ return parsePluginToolInput(
227
+ inputSchema,
228
+ prepareArguments ? prepareArguments(args) : args,
229
+ );
230
+ },
231
+ ...(execute
232
+ ? {
233
+ async execute(input, options) {
234
+ const result = await execute(
235
+ input as z.output<TInputSchema>,
236
+ options,
237
+ );
238
+ return outputSchema.parse(pluginToolResultSchema.parse(result));
239
+ },
240
+ }
241
+ : {}),
242
+ };
118
243
  }
119
244
 
120
245
  export interface SlackToolRegistrationHookContext {