@sentry/junior-plugin-api 0.146.0 → 0.148.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/context.d.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import { z } from "zod";
2
2
  import type { ZodTypeAny } from "zod";
3
- import { destinationSchema, identitySchema, localActorSchema, platformSchema, actorSchema, slackActorSchema, systemActorSchema, sourceSchema, userSchema } from "./schemas";
3
+ import { destinationSchema, identitySchema, webActorSchema, localActorSchema, platformSchema, actorSchema, slackActorSchema, systemActorSchema, sourceSchema, userSchema } from "./schemas";
4
4
  /** Runtime platform name without source or destination coordinates. */
5
5
  export type Platform = z.output<typeof platformSchema>;
6
6
  export type Actor = z.output<typeof actorSchema>;
7
7
  export type SlackActor = z.output<typeof slackActorSchema>;
8
8
  export type LocalActor = z.output<typeof localActorSchema>;
9
+ export type WebActor = z.output<typeof webActorSchema>;
9
10
  export type SystemActor = z.output<typeof systemActorSchema>;
10
11
  export type Identity = z.output<typeof identitySchema>;
11
12
  export type User = z.output<typeof userSchema>;
@@ -16,6 +17,9 @@ export type SlackSource = Extract<Source, {
16
17
  export type LocalSource = Extract<Source, {
17
18
  platform: "local";
18
19
  }>;
20
+ export type WebSource = Extract<Source, {
21
+ platform: "web";
22
+ }>;
19
23
  export type SourceVisibility = Source["visibility"];
20
24
  export type Destination = z.output<typeof destinationSchema>;
21
25
  export type SlackDestination = Extract<Destination, {
@@ -85,7 +89,14 @@ export interface LocalInvocationContext extends BaseInvocationContext {
85
89
  /** Runtime-owned source where the invocation came from. */
86
90
  source: LocalSource;
87
91
  }
88
- export type InvocationContext = LocalInvocationContext | SlackInvocationContext;
92
+ export interface WebInvocationContext extends BaseInvocationContext {
93
+ /** Existing conversation destination used for location and tool context. */
94
+ destination: Destination;
95
+ actor?: WebActor;
96
+ /** Runtime-owned dashboard/web source for this invocation. */
97
+ source: WebSource;
98
+ }
99
+ export type InvocationContext = LocalInvocationContext | SlackInvocationContext | WebInvocationContext;
89
100
  /** Build a normalized Slack source from runtime-owned Slack coordinates. */
90
101
  export declare function createSlackSource(input: {
91
102
  channelId: string;
@@ -97,6 +108,8 @@ export declare function createSlackSource(input: {
97
108
  }): SlackSource;
98
109
  /** Build a normalized local source from a local conversation id. */
99
110
  export declare function createLocalSource(conversationId: string): LocalSource;
111
+ /** Build a normalized web/dashboard source from a conversation id. */
112
+ export declare function createWebSource(conversationId: string, visibility?: SourceVisibility): WebSource;
100
113
  /** Return whether a source is private to a person or restricted group. */
101
114
  export declare function isPrivateSource(source: Source): boolean;
102
115
  /** Return the stable source identity used for idempotency and attribution. */
@@ -10,6 +10,8 @@ export declare const pluginAuthorizationSchema: z.ZodObject<{
10
10
  }, z.core.$strict>;
11
11
  /** Runtime schema for a provider account attached to stored OAuth tokens. */
12
12
  export declare const pluginProviderAccountSchema: z.ZodObject<{
13
+ displayName: z.ZodOptional<z.ZodString>;
14
+ handle: z.ZodOptional<z.ZodString>;
13
15
  id: z.ZodString;
14
16
  label: z.ZodOptional<z.ZodString>;
15
17
  url: z.ZodOptional<z.ZodString>;
@@ -17,6 +19,8 @@ export declare const pluginProviderAccountSchema: z.ZodObject<{
17
19
  /** Runtime schema for OAuth tokens stored by the host for plugin credentials. */
18
20
  export declare const pluginStoredTokensSchema: z.ZodObject<{
19
21
  account: z.ZodOptional<z.ZodObject<{
22
+ displayName: z.ZodOptional<z.ZodString>;
23
+ handle: z.ZodOptional<z.ZodString>;
20
24
  id: z.ZodString;
21
25
  label: z.ZodOptional<z.ZodString>;
22
26
  url: z.ZodOptional<z.ZodString>;
@@ -43,6 +47,8 @@ export declare const pluginCredentialHeaderTransformSchema: z.ZodObject<{
43
47
  /** Runtime schema for a short-lived plugin-issued credential lease. */
44
48
  export declare const pluginCredentialLeaseSchema: z.ZodObject<{
45
49
  account: z.ZodOptional<z.ZodObject<{
50
+ displayName: z.ZodOptional<z.ZodString>;
51
+ handle: z.ZodOptional<z.ZodString>;
46
52
  id: z.ZodString;
47
53
  label: z.ZodOptional<z.ZodString>;
48
54
  url: z.ZodOptional<z.ZodString>;
@@ -62,6 +68,8 @@ export declare const pluginCredentialLeaseSchema: z.ZodObject<{
62
68
  export declare const pluginCredentialResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
63
69
  lease: z.ZodObject<{
64
70
  account: z.ZodOptional<z.ZodObject<{
71
+ displayName: z.ZodOptional<z.ZodString>;
72
+ handle: z.ZodOptional<z.ZodString>;
65
73
  id: z.ZodString;
66
74
  label: z.ZodOptional<z.ZodString>;
67
75
  url: z.ZodOptional<z.ZodString>;
package/dist/index.js CHANGED
@@ -111,9 +111,16 @@ var localSourceSchema = z3.object({
111
111
  visibility: z3.literal("private"),
112
112
  conversationId: localConversationIdSchema
113
113
  }).strict();
114
+ var webSourceSchema = z3.object({
115
+ platform: z3.literal("web"),
116
+ visibility: sourceVisibilitySchema,
117
+ // Web can continue any existing conversation id, including Slack roots.
118
+ conversationId: exactNonBlankStringSchema
119
+ }).strict();
114
120
  var sourceSchema = z3.discriminatedUnion("platform", [
115
121
  slackSourceSchema,
116
- localSourceSchema
122
+ localSourceSchema,
123
+ webSourceSchema
117
124
  ]);
118
125
  var pluginCredentialSubjectSchema = z3.discriminatedUnion(
119
126
  "allowedWhen",
@@ -146,6 +153,10 @@ var localActorSchema = z3.object({
146
153
  ...actorProfileSchema,
147
154
  platform: z3.literal("local")
148
155
  }).strict();
156
+ var webActorSchema = z3.object({
157
+ ...actorProfileSchema,
158
+ platform: z3.literal("web")
159
+ }).strict();
149
160
  var systemActorSchema = z3.object({
150
161
  platform: z3.literal("system"),
151
162
  name: exactActorUserIdSchema
@@ -153,6 +164,7 @@ var systemActorSchema = z3.object({
153
164
  var actorSchema = z3.discriminatedUnion("platform", [
154
165
  slackActorSchema,
155
166
  localActorSchema,
167
+ webActorSchema,
156
168
  systemActorSchema
157
169
  ]);
158
170
  var identitySchema = z3.object({
@@ -250,18 +262,29 @@ function createLocalSource(conversationId) {
250
262
  conversationId
251
263
  };
252
264
  }
265
+ function createWebSource(conversationId, visibility = "public") {
266
+ return {
267
+ platform: "web",
268
+ visibility,
269
+ conversationId
270
+ };
271
+ }
253
272
  function isPrivateSource(source) {
254
273
  return source.visibility === "private";
255
274
  }
256
275
  function getSourceKey(source) {
257
- if (source.platform === "local") {
258
- return source.conversationId;
259
- }
260
- const messageKey = source.threadTs ?? source.messageTs;
261
- if (!messageKey) {
262
- return void 0;
276
+ switch (source.platform) {
277
+ case "web":
278
+ case "local":
279
+ return source.conversationId;
280
+ case "slack": {
281
+ const messageKey = source.threadTs ?? source.messageTs;
282
+ if (!messageKey) {
283
+ return void 0;
284
+ }
285
+ return `slack:${source.teamId}:${source.channelId}:${messageKey}`;
286
+ }
263
287
  }
264
- return `slack:${source.teamId}:${source.channelId}:${messageKey}`;
265
288
  }
266
289
  function isSlackDestination(destination) {
267
290
  return destination?.platform === "slack";
@@ -293,6 +316,24 @@ function definePromptContext(definition) {
293
316
  import { z as z5 } from "zod";
294
317
  var RESOURCE_EVENT_SUMMARY_MAX_LENGTH = 4e3;
295
318
  var RESOURCE_EVENT_TEXT_MAX_LENGTH = 8e3;
319
+ var RESOURCE_EVENT_DATA_MAX_KEYS = 32;
320
+ var RESOURCE_EVENT_DATA_MAX_JSON_BYTES = 4e3;
321
+ var resourceEventDataSchema = z5.record(z5.string(), z5.unknown()).superRefine((value, context) => {
322
+ const keys = Object.keys(value);
323
+ if (keys.length > RESOURCE_EVENT_DATA_MAX_KEYS) {
324
+ context.addIssue({
325
+ code: "custom",
326
+ message: `Resource event data may include at most ${RESOURCE_EVENT_DATA_MAX_KEYS} keys.`
327
+ });
328
+ }
329
+ const jsonBytes = new TextEncoder().encode(JSON.stringify(value)).byteLength;
330
+ if (jsonBytes > RESOURCE_EVENT_DATA_MAX_JSON_BYTES) {
331
+ context.addIssue({
332
+ code: "custom",
333
+ message: `Resource event data may be at most ${RESOURCE_EVENT_DATA_MAX_JSON_BYTES} JSON bytes.`
334
+ });
335
+ }
336
+ });
296
337
  var resourceEventTypeSchema = z5.string().regex(/^[a-z][a-z0-9_-]*(?:\.[a-z][a-z0-9_-]*)+$/).describe(
297
338
  "Canonical dotted event type, such as issue.closed or pull_request.review.changes_requested."
298
339
  );
@@ -374,6 +415,8 @@ var resourceEventInputSchema = z5.object({
374
415
  occurredAtMs: z5.number().finite(),
375
416
  terminal: z5.boolean().optional(),
376
417
  trustedSummary: z5.string().min(1).transform((value) => value.slice(0, RESOURCE_EVENT_SUMMARY_MAX_LENGTH)),
418
+ /** Trusted structured facts. Prefer ids and urls over long prose. */
419
+ data: resourceEventDataSchema.optional(),
377
420
  untrustedText: z5.string().transform((value) => value.slice(0, RESOURCE_EVENT_TEXT_MAX_LENGTH)).optional()
378
421
  }).strict();
379
422
  var resourceEventSchema = resourceEventInputSchema.extend({
@@ -562,6 +605,8 @@ var pluginAuthorizationSchema = z9.object({
562
605
  type: z9.literal("oauth")
563
606
  }).strict();
564
607
  var pluginProviderAccountSchema = z9.object({
608
+ displayName: nonBlankStringSchema.optional(),
609
+ handle: nonBlankStringSchema.optional(),
565
610
  id: nonBlankStringSchema,
566
611
  label: nonBlankStringSchema.optional(),
567
612
  url: nonBlankStringSchema.optional()
@@ -789,6 +834,8 @@ export {
789
834
  EgressPolicyDenied,
790
835
  PluginToolInputError,
791
836
  REQUIRED_TOOL_ANNOTATION_KEYS,
837
+ RESOURCE_EVENT_DATA_MAX_JSON_BYTES,
838
+ RESOURCE_EVENT_DATA_MAX_KEYS,
792
839
  RESOURCE_EVENT_SUMMARY_MAX_LENGTH,
793
840
  RESOURCE_EVENT_TEXT_MAX_LENGTH,
794
841
  actorSchema,
@@ -797,6 +844,7 @@ export {
797
844
  conversationEventPresentationSchema,
798
845
  createLocalSource,
799
846
  createSlackSource,
847
+ createWebSource,
800
848
  defineConversationEvent,
801
849
  defineJuniorPlugin,
802
850
  definePluginTool,
@@ -839,6 +887,7 @@ export {
839
887
  promptContextSchema,
840
888
  promptMessageSchema,
841
889
  replyAttributionSchema,
890
+ resourceEventDataSchema,
842
891
  resourceEventInputSchema,
843
892
  resourceEventSchema,
844
893
  resourceEventTypeSchema,
@@ -853,5 +902,7 @@ export {
853
902
  systemActorSchema,
854
903
  toolApprovalModeSchema,
855
904
  userSchema,
905
+ webActorSchema,
906
+ webSourceSchema,
856
907
  zodTool
857
908
  };
@@ -1,6 +1,10 @@
1
1
  import { z } from "zod";
2
2
  export declare const RESOURCE_EVENT_SUMMARY_MAX_LENGTH = 4000;
3
3
  export declare const RESOURCE_EVENT_TEXT_MAX_LENGTH = 8000;
4
+ export declare const RESOURCE_EVENT_DATA_MAX_KEYS = 32;
5
+ export declare const RESOURCE_EVENT_DATA_MAX_JSON_BYTES = 4000;
6
+ /** Small trusted facts from the plugin. The agent should not look these up again. */
7
+ export declare const resourceEventDataSchema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
4
8
  /** Canonical dotted event type published and selected across plugins. */
5
9
  export declare const resourceEventTypeSchema: z.ZodString;
6
10
  export declare const resourceTypeSchema: z.ZodString;
@@ -38,8 +42,10 @@ export declare const resourceEventInputSchema: z.ZodObject<{
38
42
  occurredAtMs: z.ZodNumber;
39
43
  terminal: z.ZodOptional<z.ZodBoolean>;
40
44
  trustedSummary: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
45
+ data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
41
46
  untrustedText: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
42
47
  }, z.core.$strict>;
48
+ export type ResourceEventData = z.output<typeof resourceEventDataSchema>;
43
49
  export type ResourceEventInput = z.output<typeof resourceEventInputSchema>;
44
50
  export declare const resourceEventSchema: z.ZodObject<{
45
51
  eventKey: z.ZodString;
@@ -48,6 +54,7 @@ export declare const resourceEventSchema: z.ZodObject<{
48
54
  occurredAtMs: z.ZodNumber;
49
55
  terminal: z.ZodOptional<z.ZodBoolean>;
50
56
  trustedSummary: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
57
+ data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
51
58
  untrustedText: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
52
59
  namespace: z.ZodString;
53
60
  }, z.core.$strict>;
package/dist/schemas.d.ts CHANGED
@@ -53,6 +53,15 @@ export declare const localSourceSchema: z.ZodObject<{
53
53
  visibility: z.ZodLiteral<"private">;
54
54
  conversationId: z.ZodString;
55
55
  }, z.core.$strict>;
56
+ /** Runtime-owned dashboard/web coordinates for the inbound invocation. */
57
+ export declare const webSourceSchema: z.ZodObject<{
58
+ platform: z.ZodLiteral<"web">;
59
+ visibility: z.ZodEnum<{
60
+ public: "public";
61
+ private: "private";
62
+ }>;
63
+ conversationId: z.ZodString;
64
+ }, z.core.$strict>;
56
65
  /** Runtime-owned provider-neutral coordinates for the inbound invocation. */
57
66
  export declare const sourceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
58
67
  platform: z.ZodLiteral<"slack">;
@@ -68,6 +77,13 @@ export declare const sourceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
68
77
  platform: z.ZodLiteral<"local">;
69
78
  visibility: z.ZodLiteral<"private">;
70
79
  conversationId: z.ZodString;
80
+ }, z.core.$strict>, z.ZodObject<{
81
+ platform: z.ZodLiteral<"web">;
82
+ visibility: z.ZodEnum<{
83
+ public: "public";
84
+ private: "private";
85
+ }>;
86
+ conversationId: z.ZodString;
71
87
  }, z.core.$strict>], "platform">;
72
88
  /** Stable user credential subject shape accepted from plugins. */
73
89
  export declare const pluginCredentialSubjectSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -95,6 +111,13 @@ export declare const localActorSchema: z.ZodObject<{
95
111
  userId: z.ZodString;
96
112
  userName: z.ZodOptional<z.ZodString>;
97
113
  }, z.core.$strict>;
114
+ export declare const webActorSchema: z.ZodObject<{
115
+ platform: z.ZodLiteral<"web">;
116
+ email: z.ZodOptional<z.ZodString>;
117
+ fullName: z.ZodOptional<z.ZodString>;
118
+ userId: z.ZodString;
119
+ userName: z.ZodOptional<z.ZodString>;
120
+ }, z.core.$strict>;
98
121
  export declare const systemActorSchema: z.ZodObject<{
99
122
  platform: z.ZodLiteral<"system">;
100
123
  name: z.ZodString;
@@ -113,6 +136,12 @@ export declare const actorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
113
136
  fullName: z.ZodOptional<z.ZodString>;
114
137
  userId: z.ZodString;
115
138
  userName: z.ZodOptional<z.ZodString>;
139
+ }, z.core.$strict>, z.ZodObject<{
140
+ platform: z.ZodLiteral<"web">;
141
+ email: z.ZodOptional<z.ZodString>;
142
+ fullName: z.ZodOptional<z.ZodString>;
143
+ userId: z.ZodString;
144
+ userName: z.ZodOptional<z.ZodString>;
116
145
  }, z.core.$strict>, z.ZodObject<{
117
146
  platform: z.ZodLiteral<"system">;
118
147
  name: z.ZodString;
@@ -187,5 +216,12 @@ export declare const dispatchOptionsSchema: z.ZodObject<{
187
216
  platform: z.ZodLiteral<"local">;
188
217
  visibility: z.ZodLiteral<"private">;
189
218
  conversationId: z.ZodString;
219
+ }, z.core.$strict>, z.ZodObject<{
220
+ platform: z.ZodLiteral<"web">;
221
+ visibility: z.ZodEnum<{
222
+ public: "public";
223
+ private: "private";
224
+ }>;
225
+ conversationId: z.ZodString;
190
226
  }, z.core.$strict>], "platform">;
191
227
  }, z.core.$strict>;
package/dist/tasks.d.ts CHANGED
@@ -31,6 +31,12 @@ export declare const pluginRunTranscriptProvenanceSchema: z.ZodObject<{
31
31
  fullName: z.ZodOptional<z.ZodString>;
32
32
  userId: z.ZodString;
33
33
  userName: z.ZodOptional<z.ZodString>;
34
+ }, z.core.$strict>, z.ZodObject<{
35
+ platform: z.ZodLiteral<"web">;
36
+ email: z.ZodOptional<z.ZodString>;
37
+ fullName: z.ZodOptional<z.ZodString>;
38
+ userId: z.ZodString;
39
+ userName: z.ZodOptional<z.ZodString>;
34
40
  }, z.core.$strict>, z.ZodObject<{
35
41
  platform: z.ZodLiteral<"system">;
36
42
  name: z.ZodString;
@@ -62,6 +68,12 @@ export declare const pluginRunTranscriptEntrySchema: z.ZodDiscriminatedUnion<[z.
62
68
  fullName: z.ZodOptional<z.ZodString>;
63
69
  userId: z.ZodString;
64
70
  userName: z.ZodOptional<z.ZodString>;
71
+ }, z.core.$strict>, z.ZodObject<{
72
+ platform: z.ZodLiteral<"web">;
73
+ email: z.ZodOptional<z.ZodString>;
74
+ fullName: z.ZodOptional<z.ZodString>;
75
+ userId: z.ZodString;
76
+ userName: z.ZodOptional<z.ZodString>;
65
77
  }, z.core.$strict>, z.ZodObject<{
66
78
  platform: z.ZodLiteral<"system">;
67
79
  name: z.ZodString;
@@ -100,6 +112,12 @@ export declare const pluginRunContextSchema: z.ZodObject<{
100
112
  fullName: z.ZodOptional<z.ZodString>;
101
113
  userId: z.ZodString;
102
114
  userName: z.ZodOptional<z.ZodString>;
115
+ }, z.core.$strict>, z.ZodObject<{
116
+ platform: z.ZodLiteral<"web">;
117
+ email: z.ZodOptional<z.ZodString>;
118
+ fullName: z.ZodOptional<z.ZodString>;
119
+ userId: z.ZodString;
120
+ userName: z.ZodOptional<z.ZodString>;
103
121
  }, z.core.$strict>, z.ZodObject<{
104
122
  platform: z.ZodLiteral<"system">;
105
123
  name: z.ZodString;
@@ -117,6 +135,12 @@ export declare const pluginRunContextSchema: z.ZodObject<{
117
135
  fullName: z.ZodOptional<z.ZodString>;
118
136
  userId: z.ZodString;
119
137
  userName: z.ZodOptional<z.ZodString>;
138
+ }, z.core.$strict>, z.ZodObject<{
139
+ platform: z.ZodLiteral<"web">;
140
+ email: z.ZodOptional<z.ZodString>;
141
+ fullName: z.ZodOptional<z.ZodString>;
142
+ userId: z.ZodString;
143
+ userName: z.ZodOptional<z.ZodString>;
120
144
  }, z.core.$strict>, z.ZodObject<{
121
145
  platform: z.ZodLiteral<"system">;
122
146
  name: z.ZodString;
@@ -136,6 +160,13 @@ export declare const pluginRunContextSchema: z.ZodObject<{
136
160
  platform: z.ZodLiteral<"local">;
137
161
  visibility: z.ZodLiteral<"private">;
138
162
  conversationId: z.ZodString;
163
+ }, z.core.$strict>, z.ZodObject<{
164
+ platform: z.ZodLiteral<"web">;
165
+ visibility: z.ZodEnum<{
166
+ public: "public";
167
+ private: "private";
168
+ }>;
169
+ conversationId: z.ZodString;
139
170
  }, z.core.$strict>], "platform">;
140
171
  transcript: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
141
172
  type: z.ZodLiteral<"message">;
@@ -162,6 +193,12 @@ export declare const pluginRunContextSchema: z.ZodObject<{
162
193
  fullName: z.ZodOptional<z.ZodString>;
163
194
  userId: z.ZodString;
164
195
  userName: z.ZodOptional<z.ZodString>;
196
+ }, z.core.$strict>, z.ZodObject<{
197
+ platform: z.ZodLiteral<"web">;
198
+ email: z.ZodOptional<z.ZodString>;
199
+ fullName: z.ZodOptional<z.ZodString>;
200
+ userId: z.ZodString;
201
+ userName: z.ZodOptional<z.ZodString>;
165
202
  }, z.core.$strict>, z.ZodObject<{
166
203
  platform: z.ZodLiteral<"system">;
167
204
  name: z.ZodString;
package/dist/tools.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { PluginContext, LocalInvocationContext, PluginEmbedder, Identity, PluginModel, Actor, SlackInvocationContext, User } from "./context";
1
+ import type { Actor, Identity, LocalInvocationContext, PluginContext, PluginEmbedder, PluginModel, SlackInvocationContext, User, WebInvocationContext } from "./context";
2
2
  import type { PluginCredentialSubject } from "./credentials";
3
3
  import type { PluginAnnotations } from "./annotations";
4
4
  import type { SlackConversationLink } from "./operations";
@@ -285,7 +285,7 @@ interface BaseToolRegistrationHookContext extends PluginContext {
285
285
  /**
286
286
  * Opaque Junior conversation/session identity for this turn.
287
287
  * Interactive Slack turns use `slack:{channelId}:{threadTs}`.
288
- * Scheduled/API turns use an internal id such as `agent-dispatch:{id}`.
288
+ * Scheduled/web turns use an internal id such as `agent-dispatch:{id}`.
289
289
  * Do not parse as Slack unless the value starts with `slack:`.
290
290
  */
291
291
  conversationId?: string;
@@ -313,5 +313,8 @@ interface SlackToolRegistrationContext extends BaseToolRegistrationHookContext,
313
313
  interface LocalToolRegistrationContext extends BaseToolRegistrationHookContext, LocalInvocationContext {
314
314
  slack?: never;
315
315
  }
316
- export type ToolRegistrationHookContext = LocalToolRegistrationContext | SlackToolRegistrationContext;
316
+ interface WebToolRegistrationContext extends BaseToolRegistrationHookContext, WebInvocationContext {
317
+ slack?: never;
318
+ }
319
+ export type ToolRegistrationHookContext = LocalToolRegistrationContext | SlackToolRegistrationContext | WebToolRegistrationContext;
317
320
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/junior-plugin-api",
3
- "version": "0.146.0",
3
+ "version": "0.148.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
package/src/context.ts CHANGED
@@ -3,6 +3,7 @@ import type { ZodTypeAny } from "zod";
3
3
  import {
4
4
  destinationSchema,
5
5
  identitySchema,
6
+ webActorSchema,
6
7
  localActorSchema,
7
8
  platformSchema,
8
9
  actorSchema,
@@ -17,12 +18,14 @@ export type Platform = z.output<typeof platformSchema>;
17
18
  export type Actor = z.output<typeof actorSchema>;
18
19
  export type SlackActor = z.output<typeof slackActorSchema>;
19
20
  export type LocalActor = z.output<typeof localActorSchema>;
21
+ export type WebActor = z.output<typeof webActorSchema>;
20
22
  export type SystemActor = z.output<typeof systemActorSchema>;
21
23
  export type Identity = z.output<typeof identitySchema>;
22
24
  export type User = z.output<typeof userSchema>;
23
25
  export type Source = z.output<typeof sourceSchema>;
24
26
  export type SlackSource = Extract<Source, { platform: "slack" }>;
25
27
  export type LocalSource = Extract<Source, { platform: "local" }>;
28
+ export type WebSource = Extract<Source, { platform: "web" }>;
26
29
  export type SourceVisibility = Source["visibility"];
27
30
 
28
31
  export type Destination = z.output<typeof destinationSchema>;
@@ -98,7 +101,18 @@ export interface LocalInvocationContext extends BaseInvocationContext {
98
101
  source: LocalSource;
99
102
  }
100
103
 
101
- export type InvocationContext = LocalInvocationContext | SlackInvocationContext;
104
+ export interface WebInvocationContext extends BaseInvocationContext {
105
+ /** Existing conversation destination used for location and tool context. */
106
+ destination: Destination;
107
+ actor?: WebActor;
108
+ /** Runtime-owned dashboard/web source for this invocation. */
109
+ source: WebSource;
110
+ }
111
+
112
+ export type InvocationContext =
113
+ | LocalInvocationContext
114
+ | SlackInvocationContext
115
+ | WebInvocationContext;
102
116
 
103
117
  /** Build a normalized Slack source from runtime-owned Slack coordinates. */
104
118
  export function createSlackSource(input: {
@@ -128,6 +142,18 @@ export function createLocalSource(conversationId: string): LocalSource {
128
142
  };
129
143
  }
130
144
 
145
+ /** Build a normalized web/dashboard source from a conversation id. */
146
+ export function createWebSource(
147
+ conversationId: string,
148
+ visibility: SourceVisibility = "public",
149
+ ): WebSource {
150
+ return {
151
+ platform: "web",
152
+ visibility,
153
+ conversationId,
154
+ };
155
+ }
156
+
131
157
  /** Return whether a source is private to a person or restricted group. */
132
158
  export function isPrivateSource(source: Source): boolean {
133
159
  return source.visibility === "private";
@@ -135,14 +161,18 @@ export function isPrivateSource(source: Source): boolean {
135
161
 
136
162
  /** Return the stable source identity used for idempotency and attribution. */
137
163
  export function getSourceKey(source: Source): string | undefined {
138
- if (source.platform === "local") {
139
- return source.conversationId;
140
- }
141
- const messageKey = source.threadTs ?? source.messageTs;
142
- if (!messageKey) {
143
- return undefined;
164
+ switch (source.platform) {
165
+ case "web":
166
+ case "local":
167
+ return source.conversationId;
168
+ case "slack": {
169
+ const messageKey = source.threadTs ?? source.messageTs;
170
+ if (!messageKey) {
171
+ return undefined;
172
+ }
173
+ return `slack:${source.teamId}:${source.channelId}:${messageKey}`;
174
+ }
144
175
  }
145
- return `slack:${source.teamId}:${source.channelId}:${messageKey}`;
146
176
  }
147
177
 
148
178
  /** Narrow a runtime destination to the Slack-specific address shape. */
@@ -21,6 +21,8 @@ export const pluginAuthorizationSchema = z
21
21
  /** Runtime schema for a provider account attached to stored OAuth tokens. */
22
22
  export const pluginProviderAccountSchema = z
23
23
  .object({
24
+ displayName: nonBlankStringSchema.optional(),
25
+ handle: nonBlankStringSchema.optional(),
24
26
  id: nonBlankStringSchema,
25
27
  label: nonBlankStringSchema.optional(),
26
28
  url: nonBlankStringSchema.optional(),
@@ -2,6 +2,28 @@ import { z } from "zod";
2
2
 
3
3
  export const RESOURCE_EVENT_SUMMARY_MAX_LENGTH = 4_000;
4
4
  export const RESOURCE_EVENT_TEXT_MAX_LENGTH = 8_000;
5
+ export const RESOURCE_EVENT_DATA_MAX_KEYS = 32;
6
+ export const RESOURCE_EVENT_DATA_MAX_JSON_BYTES = 4_000;
7
+
8
+ /** Small trusted facts from the plugin. The agent should not look these up again. */
9
+ export const resourceEventDataSchema = z
10
+ .record(z.string(), z.unknown())
11
+ .superRefine((value, context) => {
12
+ const keys = Object.keys(value);
13
+ if (keys.length > RESOURCE_EVENT_DATA_MAX_KEYS) {
14
+ context.addIssue({
15
+ code: "custom",
16
+ message: `Resource event data may include at most ${RESOURCE_EVENT_DATA_MAX_KEYS} keys.`,
17
+ });
18
+ }
19
+ const jsonBytes = new TextEncoder().encode(JSON.stringify(value)).byteLength;
20
+ if (jsonBytes > RESOURCE_EVENT_DATA_MAX_JSON_BYTES) {
21
+ context.addIssue({
22
+ code: "custom",
23
+ message: `Resource event data may be at most ${RESOURCE_EVENT_DATA_MAX_JSON_BYTES} JSON bytes.`,
24
+ });
25
+ }
26
+ });
5
27
 
6
28
  /** Canonical dotted event type published and selected across plugins. */
7
29
  export const resourceEventTypeSchema = z
@@ -124,6 +146,8 @@ export const resourceEventInputSchema = z
124
146
  .string()
125
147
  .min(1)
126
148
  .transform((value) => value.slice(0, RESOURCE_EVENT_SUMMARY_MAX_LENGTH)),
149
+ /** Trusted structured facts. Prefer ids and urls over long prose. */
150
+ data: resourceEventDataSchema.optional(),
127
151
  untrustedText: z
128
152
  .string()
129
153
  .transform((value) => value.slice(0, RESOURCE_EVENT_TEXT_MAX_LENGTH))
@@ -131,6 +155,7 @@ export const resourceEventInputSchema = z
131
155
  })
132
156
  .strict();
133
157
 
158
+ export type ResourceEventData = z.output<typeof resourceEventDataSchema>;
134
159
  export type ResourceEventInput = z.output<typeof resourceEventInputSchema>;
135
160
 
136
161
  export const resourceEventSchema = resourceEventInputSchema.extend({
package/src/schemas.ts CHANGED
@@ -71,10 +71,21 @@ export const localSourceSchema = z
71
71
  })
72
72
  .strict();
73
73
 
74
+ /** Runtime-owned dashboard/web coordinates for the inbound invocation. */
75
+ export const webSourceSchema = z
76
+ .object({
77
+ platform: z.literal("web"),
78
+ visibility: sourceVisibilitySchema,
79
+ // Web can continue any existing conversation id, including Slack roots.
80
+ conversationId: exactNonBlankStringSchema,
81
+ })
82
+ .strict();
83
+
74
84
  /** Runtime-owned provider-neutral coordinates for the inbound invocation. */
75
85
  export const sourceSchema = z.discriminatedUnion("platform", [
76
86
  slackSourceSchema,
77
87
  localSourceSchema,
88
+ webSourceSchema,
78
89
  ]);
79
90
 
80
91
  /** Stable user credential subject shape accepted from plugins. */
@@ -122,6 +133,13 @@ export const localActorSchema = z
122
133
  })
123
134
  .strict();
124
135
 
136
+ export const webActorSchema = z
137
+ .object({
138
+ ...actorProfileSchema,
139
+ platform: z.literal("web"),
140
+ })
141
+ .strict();
142
+
125
143
  export const systemActorSchema = z
126
144
  .object({
127
145
  platform: z.literal("system"),
@@ -133,6 +151,7 @@ export const systemActorSchema = z
133
151
  export const actorSchema = z.discriminatedUnion("platform", [
134
152
  slackActorSchema,
135
153
  localActorSchema,
154
+ webActorSchema,
136
155
  systemActorSchema,
137
156
  ]);
138
157
 
package/src/tools.ts CHANGED
@@ -1,12 +1,13 @@
1
1
  import type {
2
- PluginContext,
2
+ Actor,
3
+ Identity,
3
4
  LocalInvocationContext,
5
+ PluginContext,
4
6
  PluginEmbedder,
5
- Identity,
6
7
  PluginModel,
7
- Actor,
8
8
  SlackInvocationContext,
9
9
  User,
10
+ WebInvocationContext,
10
11
  } from "./context";
11
12
  import type { PluginCredentialSubject } from "./credentials";
12
13
  import type { PluginAnnotations } from "./annotations";
@@ -514,7 +515,7 @@ interface BaseToolRegistrationHookContext extends PluginContext {
514
515
  /**
515
516
  * Opaque Junior conversation/session identity for this turn.
516
517
  * Interactive Slack turns use `slack:{channelId}:{threadTs}`.
517
- * Scheduled/API turns use an internal id such as `agent-dispatch:{id}`.
518
+ * Scheduled/web turns use an internal id such as `agent-dispatch:{id}`.
518
519
  * Do not parse as Slack unless the value starts with `slack:`.
519
520
  */
520
521
  conversationId?: string;
@@ -544,6 +545,12 @@ interface LocalToolRegistrationContext
544
545
  slack?: never;
545
546
  }
546
547
 
548
+ interface WebToolRegistrationContext
549
+ extends BaseToolRegistrationHookContext, WebInvocationContext {
550
+ slack?: never;
551
+ }
552
+
547
553
  export type ToolRegistrationHookContext =
548
554
  | LocalToolRegistrationContext
549
- | SlackToolRegistrationContext;
555
+ | SlackToolRegistrationContext
556
+ | WebToolRegistrationContext;