@sentry/junior-plugin-api 0.127.0 → 0.128.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/README.md +9 -7
- package/dist/context.d.ts +3 -1
- package/dist/index.js +23 -19
- package/dist/operations.d.ts +4 -4
- package/dist/schemas.d.ts +23 -0
- package/dist/tools.d.ts +23 -26
- package/dist/user-pages.d.ts +2 -7
- package/package.json +1 -1
- package/src/context.ts +4 -0
- package/src/operations.ts +4 -4
- package/src/schemas.ts +22 -0
- package/src/tools.ts +33 -34
- package/src/user-pages.ts +2 -8
package/README.md
CHANGED
|
@@ -55,12 +55,14 @@ reports, and other typed hook surfaces exported by this package.
|
|
|
55
55
|
binds the plugin namespace and owns access to the conversation event log.
|
|
56
56
|
Event `costUsd` is additive operation cost and must not duplicate cost
|
|
57
57
|
already recorded in the conversation's agent model usage.
|
|
58
|
-
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
- Tool hooks may lazily resolve the active actor's canonical identity and linked
|
|
59
|
+
user through `ctx.users.resolveActor()`.
|
|
60
|
+
- Authenticated API route hooks receive `ctx.users.resolve(email)` for lazy
|
|
61
|
+
canonical user resolution. Routes that do not need personal ownership do not
|
|
62
|
+
query identity storage.
|
|
63
|
+
- User page readers receive the canonical viewer `User` with linked identities.
|
|
64
|
+
Plugins return bounded data and do not mount their own page routes or browser
|
|
65
|
+
code.
|
|
64
66
|
|
|
65
67
|
## User Pages
|
|
66
68
|
|
|
@@ -72,7 +74,7 @@ Set `navigation: "primary"` for a top-level dashboard navigation item. The
|
|
|
72
74
|
default `profile` placement keeps account-oriented pages in the signed-in user
|
|
73
75
|
menu. Junior always renders core System navigation after plugin pages.
|
|
74
76
|
Records may expose bounded `DELETE` actions inside their own authenticated
|
|
75
|
-
plugin API namespace. Core owns discovery, authentication,
|
|
77
|
+
plugin API namespace. Core owns discovery, authentication, user resolution,
|
|
76
78
|
routing, response validation, rendering, confirmation, and query state.
|
|
77
79
|
|
|
78
80
|
## Durable Work
|
package/dist/context.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import type { ZodTypeAny } from "zod";
|
|
3
|
-
import { destinationSchema, localActorSchema, platformSchema, actorSchema, slackActorSchema, systemActorSchema, sourceSchema } from "./schemas";
|
|
3
|
+
import { destinationSchema, identitySchema, 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
9
|
export type SystemActor = z.output<typeof systemActorSchema>;
|
|
10
|
+
export type Identity = z.output<typeof identitySchema>;
|
|
11
|
+
export type User = z.output<typeof userSchema>;
|
|
10
12
|
export type Source = z.output<typeof sourceSchema>;
|
|
11
13
|
export type SlackSource = Extract<Source, {
|
|
12
14
|
platform: "slack";
|
package/dist/index.js
CHANGED
|
@@ -154,6 +154,20 @@ var actorSchema = z3.discriminatedUnion("platform", [
|
|
|
154
154
|
localActorSchema,
|
|
155
155
|
systemActorSchema
|
|
156
156
|
]);
|
|
157
|
+
var identitySchema = z3.object({
|
|
158
|
+
displayName: nonBlankStringSchema.optional(),
|
|
159
|
+
handle: nonBlankStringSchema.optional(),
|
|
160
|
+
id: exactNonBlankStringSchema,
|
|
161
|
+
provider: exactNonBlankStringSchema,
|
|
162
|
+
providerSubjectId: exactNonBlankStringSchema,
|
|
163
|
+
providerTenantId: exactNonBlankStringSchema.optional()
|
|
164
|
+
}).strict();
|
|
165
|
+
var userSchema = z3.object({
|
|
166
|
+
displayName: nonBlankStringSchema.optional(),
|
|
167
|
+
email: nonBlankStringSchema.max(320),
|
|
168
|
+
id: exactNonBlankStringSchema,
|
|
169
|
+
identities: z3.array(identitySchema).max(100)
|
|
170
|
+
}).strict();
|
|
157
171
|
var dispatchMetadataSchema = z3.record(z3.string(), z3.string()).superRefine((metadata, ctx) => {
|
|
158
172
|
const entries = Object.entries(metadata);
|
|
159
173
|
if (entries.length > 20) {
|
|
@@ -429,19 +443,10 @@ var pluginToolContinuationSchema = z7.object({
|
|
|
429
443
|
arguments: z7.record(z7.string(), z7.unknown()),
|
|
430
444
|
reason: z7.string().min(1).optional()
|
|
431
445
|
}).strict();
|
|
432
|
-
var
|
|
433
|
-
kind: z7.string().min(1),
|
|
434
|
-
message: z7.string().min(1),
|
|
435
|
-
retryable: z7.boolean().optional()
|
|
436
|
-
}).strict();
|
|
437
|
-
var pluginToolResultSchema = z7.object({
|
|
438
|
-
ok: z7.boolean(),
|
|
439
|
-
status: z7.enum(["success", "error"]),
|
|
446
|
+
var pluginToolOutputSchema = z7.object({
|
|
440
447
|
target: z7.string().min(1).optional(),
|
|
441
|
-
data: z7.unknown().optional(),
|
|
442
448
|
truncated: z7.boolean().optional(),
|
|
443
|
-
continuation: pluginToolContinuationSchema.optional()
|
|
444
|
-
error: z7.union([pluginToolErrorSchema, z7.string()]).optional()
|
|
449
|
+
continuation: pluginToolContinuationSchema.optional()
|
|
445
450
|
}).passthrough();
|
|
446
451
|
var toolApprovalModeSchema = z7.enum(["auto", "review", "approve"]);
|
|
447
452
|
var REQUIRED_TOOL_ANNOTATION_KEYS = [
|
|
@@ -455,7 +460,7 @@ function missingToolAnnotationKeys(annotations) {
|
|
|
455
460
|
(key) => typeof annotations?.[key] !== "boolean"
|
|
456
461
|
);
|
|
457
462
|
}
|
|
458
|
-
function
|
|
463
|
+
function isPluginToolOutputEnvelope(value) {
|
|
459
464
|
return value !== null && typeof value === "object" && Array.isArray(value.content) && "details" in value;
|
|
460
465
|
}
|
|
461
466
|
function formatZodPath(path) {
|
|
@@ -511,15 +516,13 @@ function createZodTool(definition, helperName) {
|
|
|
511
516
|
input,
|
|
512
517
|
options
|
|
513
518
|
);
|
|
514
|
-
if (
|
|
519
|
+
if (isPluginToolOutputEnvelope(result)) {
|
|
515
520
|
return {
|
|
516
521
|
content: z7.array(pluginToolContentSchema).parse(result.content),
|
|
517
|
-
details: outputSchema.parse(
|
|
518
|
-
pluginToolResultSchema.parse(result.details)
|
|
519
|
-
)
|
|
522
|
+
details: outputSchema.parse(result.details)
|
|
520
523
|
};
|
|
521
524
|
}
|
|
522
|
-
return outputSchema.parse(
|
|
525
|
+
return outputSchema.parse(result);
|
|
523
526
|
}
|
|
524
527
|
} : {}
|
|
525
528
|
};
|
|
@@ -801,6 +804,7 @@ export {
|
|
|
801
804
|
destinationVisibilitySchema,
|
|
802
805
|
dispatchOptionsSchema,
|
|
803
806
|
getSourceKey,
|
|
807
|
+
identitySchema,
|
|
804
808
|
isPrivateSource,
|
|
805
809
|
isSlackDestination,
|
|
806
810
|
localActorSchema,
|
|
@@ -826,8 +830,7 @@ export {
|
|
|
826
830
|
pluginStoredTokensSchema,
|
|
827
831
|
pluginToolContentSchema,
|
|
828
832
|
pluginToolContinuationSchema,
|
|
829
|
-
|
|
830
|
-
pluginToolResultSchema,
|
|
833
|
+
pluginToolOutputSchema,
|
|
831
834
|
pluginUserPageContentSchema,
|
|
832
835
|
pluginUserPageInputSchema,
|
|
833
836
|
pluginUserPageLinkSchema,
|
|
@@ -848,5 +851,6 @@ export {
|
|
|
848
851
|
subscribableResourceSchema,
|
|
849
852
|
systemActorSchema,
|
|
850
853
|
toolApprovalModeSchema,
|
|
854
|
+
userSchema,
|
|
851
855
|
zodTool
|
|
852
856
|
};
|
package/dist/operations.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import type {
|
|
2
|
+
import type { PluginContext, User } from "./context";
|
|
3
3
|
import type { Dispatch, DispatchOptions, DispatchResult } from "./dispatch";
|
|
4
4
|
import type { PluginReadState, PluginState } from "./state";
|
|
5
5
|
import type { ResourceEventPublisher } from "./resource-events";
|
|
@@ -93,9 +93,9 @@ export interface RouteRegistrationHookContext extends PluginContext {
|
|
|
93
93
|
}
|
|
94
94
|
export interface ApiRouteRegistrationHookContext extends PluginContext {
|
|
95
95
|
eventStats: PluginConversationEventStats;
|
|
96
|
-
|
|
97
|
-
/** Resolve
|
|
98
|
-
|
|
96
|
+
users: {
|
|
97
|
+
/** Resolve or create the canonical user for one verified email. */
|
|
98
|
+
resolve(email: string): Promise<User | undefined>;
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
101
|
/** Per-request context Junior passes to authenticated plugin product API routes. */
|
package/dist/schemas.d.ts
CHANGED
|
@@ -117,6 +117,29 @@ export declare const actorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
117
117
|
platform: z.ZodLiteral<"system">;
|
|
118
118
|
name: z.ZodString;
|
|
119
119
|
}, z.core.$strict>], "platform">;
|
|
120
|
+
/** Core-owned provider account linked to a user when verified. */
|
|
121
|
+
export declare const identitySchema: z.ZodObject<{
|
|
122
|
+
displayName: z.ZodOptional<z.ZodString>;
|
|
123
|
+
handle: z.ZodOptional<z.ZodString>;
|
|
124
|
+
id: z.ZodString;
|
|
125
|
+
provider: z.ZodString;
|
|
126
|
+
providerSubjectId: z.ZodString;
|
|
127
|
+
providerTenantId: z.ZodOptional<z.ZodString>;
|
|
128
|
+
}, z.core.$strict>;
|
|
129
|
+
/** Core-owned person with every linked provider identity. */
|
|
130
|
+
export declare const userSchema: z.ZodObject<{
|
|
131
|
+
displayName: z.ZodOptional<z.ZodString>;
|
|
132
|
+
email: z.ZodString;
|
|
133
|
+
id: z.ZodString;
|
|
134
|
+
identities: z.ZodArray<z.ZodObject<{
|
|
135
|
+
displayName: z.ZodOptional<z.ZodString>;
|
|
136
|
+
handle: z.ZodOptional<z.ZodString>;
|
|
137
|
+
id: z.ZodString;
|
|
138
|
+
provider: z.ZodString;
|
|
139
|
+
providerSubjectId: z.ZodString;
|
|
140
|
+
providerTenantId: z.ZodOptional<z.ZodString>;
|
|
141
|
+
}, z.core.$strict>>;
|
|
142
|
+
}, z.core.$strict>;
|
|
120
143
|
/** Compact destination-visible context explaining what produced a reply. */
|
|
121
144
|
export declare const replyAttributionSchema: z.ZodObject<{
|
|
122
145
|
label: z.ZodPipe<z.ZodString, z.ZodString>;
|
package/dist/tools.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { PluginContext, LocalInvocationContext, PluginEmbedder, PluginModel, Actor, SlackInvocationContext } from "./context";
|
|
1
|
+
import type { PluginContext, LocalInvocationContext, PluginEmbedder, Identity, PluginModel, Actor, SlackInvocationContext, User } from "./context";
|
|
2
2
|
import type { PluginCredentialSubject } from "./credentials";
|
|
3
3
|
import type { PluginAnnotations } from "./annotations";
|
|
4
4
|
import type { SlackConversationLink } from "./operations";
|
|
5
5
|
import type { PluginState } from "./state";
|
|
6
|
-
import { z, type
|
|
6
|
+
import { z, type ZodTypeAny } from "zod";
|
|
7
7
|
export interface PluginEnv {
|
|
8
8
|
get(key: string): string | undefined;
|
|
9
9
|
set(key: string, value: string): void;
|
|
@@ -63,8 +63,8 @@ export declare const pluginToolContentSchema: z.ZodDiscriminatedUnion<[z.ZodObje
|
|
|
63
63
|
}, z.core.$strict>], "type">;
|
|
64
64
|
/** Model-visible content returned by a plugin tool. */
|
|
65
65
|
export type PluginToolContent = z.output<typeof pluginToolContentSchema>;
|
|
66
|
-
/**
|
|
67
|
-
export interface
|
|
66
|
+
/** Pi-native projection with model-facing content and canonical runtime details. */
|
|
67
|
+
export interface PluginToolOutputEnvelope<TDetails = unknown> {
|
|
68
68
|
content: PluginToolContent[];
|
|
69
69
|
details: TDetails;
|
|
70
70
|
}
|
|
@@ -159,31 +159,16 @@ export declare const pluginToolContinuationSchema: z.ZodObject<{
|
|
|
159
159
|
arguments: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
160
160
|
reason: z.ZodOptional<z.ZodString>;
|
|
161
161
|
}, z.core.$strict>;
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
message: z.ZodString;
|
|
165
|
-
retryable: z.ZodOptional<z.ZodBoolean>;
|
|
166
|
-
}, z.core.$strict>;
|
|
167
|
-
export declare const pluginToolResultSchema: z.ZodObject<{
|
|
168
|
-
ok: z.ZodBoolean;
|
|
169
|
-
status: z.ZodEnum<{
|
|
170
|
-
error: "error";
|
|
171
|
-
success: "success";
|
|
172
|
-
}>;
|
|
162
|
+
/** Shared optional fields for canonical plugin tool outputs. */
|
|
163
|
+
export declare const pluginToolOutputSchema: z.ZodObject<{
|
|
173
164
|
target: z.ZodOptional<z.ZodString>;
|
|
174
|
-
data: z.ZodOptional<z.ZodUnknown>;
|
|
175
165
|
truncated: z.ZodOptional<z.ZodBoolean>;
|
|
176
166
|
continuation: z.ZodOptional<z.ZodObject<{
|
|
177
167
|
arguments: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
178
168
|
reason: z.ZodOptional<z.ZodString>;
|
|
179
169
|
}, z.core.$strict>>;
|
|
180
|
-
error: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
|
|
181
|
-
kind: z.ZodString;
|
|
182
|
-
message: z.ZodString;
|
|
183
|
-
retryable: z.ZodOptional<z.ZodBoolean>;
|
|
184
|
-
}, z.core.$strict>, z.ZodString]>>;
|
|
185
170
|
}, z.core.$loose>;
|
|
186
|
-
export type
|
|
171
|
+
export type PluginToolOutput = z.output<typeof pluginToolOutputSchema>;
|
|
187
172
|
export type PluginToolExecute<TInput = unknown, TOutput = unknown> = {
|
|
188
173
|
bivarianceHack(input: TInput, options: PluginToolExecuteOptions): Promise<TOutput> | TOutput;
|
|
189
174
|
}["bivarianceHack"];
|
|
@@ -262,17 +247,17 @@ export interface PluginToolDefinition<TInput = unknown, TOutput = unknown, TExec
|
|
|
262
247
|
promptSnippet?: string;
|
|
263
248
|
execute?: PluginToolExecute<TInput, TExecuteOutput>;
|
|
264
249
|
}
|
|
265
|
-
type ZodPluginToolDefinition<TInputSchema extends ZodTypeAny, TOutputSchema extends
|
|
250
|
+
type ZodPluginToolDefinition<TInputSchema extends ZodTypeAny, TOutputSchema extends ZodTypeAny, TExecuteResult extends z.input<TOutputSchema> | PluginToolOutputEnvelope<z.input<TOutputSchema>>> = Omit<PluginToolDefinition<z.output<TInputSchema>, z.output<TOutputSchema>>, "inputSchema" | "outputSchema" | "prepareArguments" | "execute"> & {
|
|
266
251
|
inputSchema: TInputSchema;
|
|
267
252
|
outputSchema: TOutputSchema;
|
|
268
253
|
prepareArguments?: (args: unknown) => z.input<TInputSchema>;
|
|
269
254
|
execute?: (input: z.output<TInputSchema>, options: PluginToolExecuteOptions) => Promise<TExecuteResult> | TExecuteResult;
|
|
270
255
|
};
|
|
271
|
-
type ParsedPluginToolExecuteResult<TOutputSchema extends ZodTypeAny, TResult> = TResult extends
|
|
256
|
+
type ParsedPluginToolExecuteResult<TOutputSchema extends ZodTypeAny, TResult> = TResult extends PluginToolOutputEnvelope<unknown> ? PluginToolOutputEnvelope<z.output<TOutputSchema>> : z.output<TOutputSchema>;
|
|
272
257
|
/** Define a plugin tool with Zod input parsing and validated structured results. */
|
|
273
|
-
export declare function zodTool<TInputSchema extends ZodTypeAny, TOutputSchema extends
|
|
258
|
+
export declare function zodTool<TInputSchema extends ZodTypeAny, TOutputSchema extends ZodTypeAny, TExecuteResult extends z.input<TOutputSchema> | PluginToolOutputEnvelope<z.input<TOutputSchema>>>(definition: ZodPluginToolDefinition<TInputSchema, TOutputSchema, TExecuteResult>): PluginToolDefinition<z.output<TInputSchema>, z.output<TOutputSchema>, ParsedPluginToolExecuteResult<TOutputSchema, TExecuteResult>>;
|
|
274
259
|
/** Define a plugin tool with Zod input parsing and the structured result contract. */
|
|
275
|
-
export declare function definePluginTool<TInputSchema extends ZodTypeAny, TOutputSchema extends
|
|
260
|
+
export declare function definePluginTool<TInputSchema extends ZodTypeAny, TOutputSchema extends ZodTypeAny, TExecuteResult extends z.input<TOutputSchema> | PluginToolOutputEnvelope<z.input<TOutputSchema>>>(definition: ZodPluginToolDefinition<TInputSchema, TOutputSchema, TExecuteResult>): PluginToolDefinition<z.output<TInputSchema>, z.output<TOutputSchema>, ParsedPluginToolExecuteResult<TOutputSchema, TExecuteResult>>;
|
|
276
261
|
export interface SlackToolRegistrationHookContext {
|
|
277
262
|
/**
|
|
278
263
|
* Capabilities of the source Slack conversation exposed to this plugin.
|
|
@@ -289,6 +274,10 @@ export interface SlackToolRegistrationHookContext {
|
|
|
289
274
|
allowedWhen: "private-direct-conversation";
|
|
290
275
|
}>;
|
|
291
276
|
}
|
|
277
|
+
export interface PluginResourceEventToolContext {
|
|
278
|
+
/** Whether this invocation can create a working resource-event subscription. */
|
|
279
|
+
canSubscribe: boolean;
|
|
280
|
+
}
|
|
292
281
|
interface BaseToolRegistrationHookContext extends PluginContext {
|
|
293
282
|
/**
|
|
294
283
|
* Opaque Junior conversation/session identity for this turn.
|
|
@@ -302,7 +291,15 @@ interface BaseToolRegistrationHookContext extends PluginContext {
|
|
|
302
291
|
egress: PluginEgress;
|
|
303
292
|
mcp?: PluginMcp;
|
|
304
293
|
model: PluginModel;
|
|
294
|
+
resourceEvents: PluginResourceEventToolContext;
|
|
305
295
|
state: PluginState;
|
|
296
|
+
users: {
|
|
297
|
+
/** Resolve the current actor's stored identity and linked user. */
|
|
298
|
+
resolveActor(): Promise<{
|
|
299
|
+
identity: Identity;
|
|
300
|
+
user?: User;
|
|
301
|
+
} | undefined>;
|
|
302
|
+
};
|
|
306
303
|
userText?: string;
|
|
307
304
|
}
|
|
308
305
|
interface SlackToolRegistrationContext extends BaseToolRegistrationHookContext, SlackInvocationContext {
|
package/dist/user-pages.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* routing, response validation, and browser rendering.
|
|
6
6
|
*/
|
|
7
7
|
import { z } from "zod";
|
|
8
|
-
import type {
|
|
8
|
+
import type { PluginContext, User } from "./context";
|
|
9
9
|
/** Bounded list content returned by a plugin-owned user page. */
|
|
10
10
|
export declare const pluginUserPageContentSchema: z.ZodObject<{
|
|
11
11
|
emptyText: z.ZodOptional<z.ZodString>;
|
|
@@ -76,14 +76,9 @@ export declare const pluginUserPageInputSchema: z.ZodObject<{
|
|
|
76
76
|
query: z.ZodOptional<z.ZodString>;
|
|
77
77
|
}, z.core.$strict>;
|
|
78
78
|
export type PluginUserPageInput = z.output<typeof pluginUserPageInputSchema>;
|
|
79
|
-
/** Runtime-owned actor shapes that may belong to an authenticated viewer. */
|
|
80
|
-
export type PluginUserPageActor = SlackActor | LocalActor;
|
|
81
79
|
/** Trusted host context supplied while reading one plugin user page. */
|
|
82
80
|
export interface PluginUserPageContext extends PluginContext {
|
|
83
|
-
viewer:
|
|
84
|
-
actors: PluginUserPageActor[];
|
|
85
|
-
email: string;
|
|
86
|
-
};
|
|
81
|
+
viewer: User;
|
|
87
82
|
}
|
|
88
83
|
/** Navigation metadata and reader for one core-rendered plugin user page. */
|
|
89
84
|
export interface PluginUserPageDefinition {
|
package/package.json
CHANGED
package/src/context.ts
CHANGED
|
@@ -2,12 +2,14 @@ import { z } from "zod";
|
|
|
2
2
|
import type { ZodTypeAny } from "zod";
|
|
3
3
|
import {
|
|
4
4
|
destinationSchema,
|
|
5
|
+
identitySchema,
|
|
5
6
|
localActorSchema,
|
|
6
7
|
platformSchema,
|
|
7
8
|
actorSchema,
|
|
8
9
|
slackActorSchema,
|
|
9
10
|
systemActorSchema,
|
|
10
11
|
sourceSchema,
|
|
12
|
+
userSchema,
|
|
11
13
|
} from "./schemas";
|
|
12
14
|
|
|
13
15
|
/** Runtime platform name without source or destination coordinates. */
|
|
@@ -16,6 +18,8 @@ export type Actor = z.output<typeof actorSchema>;
|
|
|
16
18
|
export type SlackActor = z.output<typeof slackActorSchema>;
|
|
17
19
|
export type LocalActor = z.output<typeof localActorSchema>;
|
|
18
20
|
export type SystemActor = z.output<typeof systemActorSchema>;
|
|
21
|
+
export type Identity = z.output<typeof identitySchema>;
|
|
22
|
+
export type User = z.output<typeof userSchema>;
|
|
19
23
|
export type Source = z.output<typeof sourceSchema>;
|
|
20
24
|
export type SlackSource = Extract<Source, { platform: "slack" }>;
|
|
21
25
|
export type LocalSource = Extract<Source, { platform: "local" }>;
|
package/src/operations.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import type {
|
|
2
|
+
import type { PluginContext, User } from "./context";
|
|
3
3
|
import type { Dispatch, DispatchOptions, DispatchResult } from "./dispatch";
|
|
4
4
|
import { nonBlankStringSchema } from "./schemas";
|
|
5
5
|
import type { PluginReadState, PluginState } from "./state";
|
|
@@ -124,9 +124,9 @@ export interface RouteRegistrationHookContext extends PluginContext {
|
|
|
124
124
|
|
|
125
125
|
export interface ApiRouteRegistrationHookContext extends PluginContext {
|
|
126
126
|
eventStats: PluginConversationEventStats;
|
|
127
|
-
|
|
128
|
-
/** Resolve
|
|
129
|
-
|
|
127
|
+
users: {
|
|
128
|
+
/** Resolve or create the canonical user for one verified email. */
|
|
129
|
+
resolve(email: string): Promise<User | undefined>;
|
|
130
130
|
};
|
|
131
131
|
}
|
|
132
132
|
|
package/src/schemas.ts
CHANGED
|
@@ -136,6 +136,28 @@ export const actorSchema = z.discriminatedUnion("platform", [
|
|
|
136
136
|
systemActorSchema,
|
|
137
137
|
]);
|
|
138
138
|
|
|
139
|
+
/** Core-owned provider account linked to a user when verified. */
|
|
140
|
+
export const identitySchema = z
|
|
141
|
+
.object({
|
|
142
|
+
displayName: nonBlankStringSchema.optional(),
|
|
143
|
+
handle: nonBlankStringSchema.optional(),
|
|
144
|
+
id: exactNonBlankStringSchema,
|
|
145
|
+
provider: exactNonBlankStringSchema,
|
|
146
|
+
providerSubjectId: exactNonBlankStringSchema,
|
|
147
|
+
providerTenantId: exactNonBlankStringSchema.optional(),
|
|
148
|
+
})
|
|
149
|
+
.strict();
|
|
150
|
+
|
|
151
|
+
/** Core-owned person with every linked provider identity. */
|
|
152
|
+
export const userSchema = z
|
|
153
|
+
.object({
|
|
154
|
+
displayName: nonBlankStringSchema.optional(),
|
|
155
|
+
email: nonBlankStringSchema.max(320),
|
|
156
|
+
id: exactNonBlankStringSchema,
|
|
157
|
+
identities: z.array(identitySchema).max(100),
|
|
158
|
+
})
|
|
159
|
+
.strict();
|
|
160
|
+
|
|
139
161
|
const dispatchMetadataSchema = z
|
|
140
162
|
.record(z.string(), z.string())
|
|
141
163
|
.superRefine((metadata, ctx) => {
|
package/src/tools.ts
CHANGED
|
@@ -2,15 +2,17 @@ import type {
|
|
|
2
2
|
PluginContext,
|
|
3
3
|
LocalInvocationContext,
|
|
4
4
|
PluginEmbedder,
|
|
5
|
+
Identity,
|
|
5
6
|
PluginModel,
|
|
6
7
|
Actor,
|
|
7
8
|
SlackInvocationContext,
|
|
9
|
+
User,
|
|
8
10
|
} from "./context";
|
|
9
11
|
import type { PluginCredentialSubject } from "./credentials";
|
|
10
12
|
import type { PluginAnnotations } from "./annotations";
|
|
11
13
|
import type { SlackConversationLink } from "./operations";
|
|
12
14
|
import type { PluginState } from "./state";
|
|
13
|
-
import { z, type
|
|
15
|
+
import { z, type ZodTypeAny } from "zod";
|
|
14
16
|
|
|
15
17
|
export interface PluginEnv {
|
|
16
18
|
get(key: string): string | undefined;
|
|
@@ -81,8 +83,8 @@ export const pluginToolContentSchema = z.discriminatedUnion("type", [
|
|
|
81
83
|
/** Model-visible content returned by a plugin tool. */
|
|
82
84
|
export type PluginToolContent = z.output<typeof pluginToolContentSchema>;
|
|
83
85
|
|
|
84
|
-
/**
|
|
85
|
-
export interface
|
|
86
|
+
/** Pi-native projection with model-facing content and canonical runtime details. */
|
|
87
|
+
export interface PluginToolOutputEnvelope<TDetails = unknown> {
|
|
86
88
|
content: PluginToolContent[];
|
|
87
89
|
details: TDetails;
|
|
88
90
|
}
|
|
@@ -194,27 +196,16 @@ export const pluginToolContinuationSchema = z
|
|
|
194
196
|
})
|
|
195
197
|
.strict();
|
|
196
198
|
|
|
197
|
-
|
|
199
|
+
/** Shared optional fields for canonical plugin tool outputs. */
|
|
200
|
+
export const pluginToolOutputSchema = z
|
|
198
201
|
.object({
|
|
199
|
-
kind: z.string().min(1),
|
|
200
|
-
message: z.string().min(1),
|
|
201
|
-
retryable: z.boolean().optional(),
|
|
202
|
-
})
|
|
203
|
-
.strict();
|
|
204
|
-
|
|
205
|
-
export const pluginToolResultSchema = z
|
|
206
|
-
.object({
|
|
207
|
-
ok: z.boolean(),
|
|
208
|
-
status: z.enum(["success", "error"]),
|
|
209
202
|
target: z.string().min(1).optional(),
|
|
210
|
-
data: z.unknown().optional(),
|
|
211
203
|
truncated: z.boolean().optional(),
|
|
212
204
|
continuation: pluginToolContinuationSchema.optional(),
|
|
213
|
-
error: z.union([pluginToolErrorSchema, z.string()]).optional(),
|
|
214
205
|
})
|
|
215
206
|
.passthrough();
|
|
216
207
|
|
|
217
|
-
export type
|
|
208
|
+
export type PluginToolOutput = z.output<typeof pluginToolOutputSchema>;
|
|
218
209
|
|
|
219
210
|
export type PluginToolExecute<TInput = unknown, TOutput = unknown> = {
|
|
220
211
|
bivarianceHack(
|
|
@@ -320,10 +311,10 @@ export interface PluginToolDefinition<
|
|
|
320
311
|
|
|
321
312
|
type ZodPluginToolDefinition<
|
|
322
313
|
TInputSchema extends ZodTypeAny,
|
|
323
|
-
TOutputSchema extends
|
|
314
|
+
TOutputSchema extends ZodTypeAny,
|
|
324
315
|
TExecuteResult extends
|
|
325
316
|
| z.input<TOutputSchema>
|
|
326
|
-
|
|
|
317
|
+
| PluginToolOutputEnvelope<z.input<TOutputSchema>>,
|
|
327
318
|
> = Omit<
|
|
328
319
|
PluginToolDefinition<z.output<TInputSchema>, z.output<TOutputSchema>>,
|
|
329
320
|
"inputSchema" | "outputSchema" | "prepareArguments" | "execute"
|
|
@@ -338,13 +329,13 @@ type ZodPluginToolDefinition<
|
|
|
338
329
|
};
|
|
339
330
|
|
|
340
331
|
type ParsedPluginToolExecuteResult<TOutputSchema extends ZodTypeAny, TResult> =
|
|
341
|
-
TResult extends
|
|
342
|
-
?
|
|
332
|
+
TResult extends PluginToolOutputEnvelope<unknown>
|
|
333
|
+
? PluginToolOutputEnvelope<z.output<TOutputSchema>>
|
|
343
334
|
: z.output<TOutputSchema>;
|
|
344
335
|
|
|
345
|
-
function
|
|
336
|
+
function isPluginToolOutputEnvelope(
|
|
346
337
|
value: unknown,
|
|
347
|
-
): value is
|
|
338
|
+
): value is PluginToolOutputEnvelope<unknown> {
|
|
348
339
|
return (
|
|
349
340
|
value !== null &&
|
|
350
341
|
typeof value === "object" &&
|
|
@@ -380,10 +371,10 @@ function parsePluginToolInput<TInputSchema extends ZodTypeAny>(
|
|
|
380
371
|
|
|
381
372
|
function createZodTool<
|
|
382
373
|
TInputSchema extends ZodTypeAny,
|
|
383
|
-
TOutputSchema extends
|
|
374
|
+
TOutputSchema extends ZodTypeAny,
|
|
384
375
|
TExecuteResult extends
|
|
385
376
|
| z.input<TOutputSchema>
|
|
386
|
-
|
|
|
377
|
+
| PluginToolOutputEnvelope<z.input<TOutputSchema>>,
|
|
387
378
|
>(
|
|
388
379
|
definition: ZodPluginToolDefinition<
|
|
389
380
|
TInputSchema,
|
|
@@ -434,15 +425,13 @@ function createZodTool<
|
|
|
434
425
|
input as z.output<TInputSchema>,
|
|
435
426
|
options,
|
|
436
427
|
);
|
|
437
|
-
if (
|
|
428
|
+
if (isPluginToolOutputEnvelope(result)) {
|
|
438
429
|
return {
|
|
439
430
|
content: z.array(pluginToolContentSchema).parse(result.content),
|
|
440
|
-
details: outputSchema.parse(
|
|
441
|
-
pluginToolResultSchema.parse(result.details),
|
|
442
|
-
),
|
|
431
|
+
details: outputSchema.parse(result.details),
|
|
443
432
|
};
|
|
444
433
|
}
|
|
445
|
-
return outputSchema.parse(
|
|
434
|
+
return outputSchema.parse(result);
|
|
446
435
|
},
|
|
447
436
|
}
|
|
448
437
|
: {}),
|
|
@@ -456,10 +445,10 @@ function createZodTool<
|
|
|
456
445
|
/** Define a plugin tool with Zod input parsing and validated structured results. */
|
|
457
446
|
export function zodTool<
|
|
458
447
|
TInputSchema extends ZodTypeAny,
|
|
459
|
-
TOutputSchema extends
|
|
448
|
+
TOutputSchema extends ZodTypeAny,
|
|
460
449
|
TExecuteResult extends
|
|
461
450
|
| z.input<TOutputSchema>
|
|
462
|
-
|
|
|
451
|
+
| PluginToolOutputEnvelope<z.input<TOutputSchema>>,
|
|
463
452
|
>(
|
|
464
453
|
definition: ZodPluginToolDefinition<
|
|
465
454
|
TInputSchema,
|
|
@@ -477,10 +466,10 @@ export function zodTool<
|
|
|
477
466
|
/** Define a plugin tool with Zod input parsing and the structured result contract. */
|
|
478
467
|
export function definePluginTool<
|
|
479
468
|
TInputSchema extends ZodTypeAny,
|
|
480
|
-
TOutputSchema extends
|
|
469
|
+
TOutputSchema extends ZodTypeAny,
|
|
481
470
|
TExecuteResult extends
|
|
482
471
|
| z.input<TOutputSchema>
|
|
483
|
-
|
|
|
472
|
+
| PluginToolOutputEnvelope<z.input<TOutputSchema>>,
|
|
484
473
|
>(
|
|
485
474
|
definition: ZodPluginToolDefinition<
|
|
486
475
|
TInputSchema,
|
|
@@ -513,6 +502,11 @@ export interface SlackToolRegistrationHookContext {
|
|
|
513
502
|
>;
|
|
514
503
|
}
|
|
515
504
|
|
|
505
|
+
export interface PluginResourceEventToolContext {
|
|
506
|
+
/** Whether this invocation can create a working resource-event subscription. */
|
|
507
|
+
canSubscribe: boolean;
|
|
508
|
+
}
|
|
509
|
+
|
|
516
510
|
interface BaseToolRegistrationHookContext extends PluginContext {
|
|
517
511
|
/**
|
|
518
512
|
* Opaque Junior conversation/session identity for this turn.
|
|
@@ -526,7 +520,12 @@ interface BaseToolRegistrationHookContext extends PluginContext {
|
|
|
526
520
|
egress: PluginEgress;
|
|
527
521
|
mcp?: PluginMcp;
|
|
528
522
|
model: PluginModel;
|
|
523
|
+
resourceEvents: PluginResourceEventToolContext;
|
|
529
524
|
state: PluginState;
|
|
525
|
+
users: {
|
|
526
|
+
/** Resolve the current actor's stored identity and linked user. */
|
|
527
|
+
resolveActor(): Promise<{ identity: Identity; user?: User } | undefined>;
|
|
528
|
+
};
|
|
530
529
|
userText?: string;
|
|
531
530
|
}
|
|
532
531
|
|
package/src/user-pages.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* routing, response validation, and browser rendering.
|
|
6
6
|
*/
|
|
7
7
|
import { z } from "zod";
|
|
8
|
-
import type {
|
|
8
|
+
import type { PluginContext, User } from "./context";
|
|
9
9
|
import { nonBlankStringSchema } from "./schemas";
|
|
10
10
|
|
|
11
11
|
const userPageIdSchema = nonBlankStringSchema
|
|
@@ -98,15 +98,9 @@ export const pluginUserPageInputSchema = z
|
|
|
98
98
|
|
|
99
99
|
export type PluginUserPageInput = z.output<typeof pluginUserPageInputSchema>;
|
|
100
100
|
|
|
101
|
-
/** Runtime-owned actor shapes that may belong to an authenticated viewer. */
|
|
102
|
-
export type PluginUserPageActor = SlackActor | LocalActor;
|
|
103
|
-
|
|
104
101
|
/** Trusted host context supplied while reading one plugin user page. */
|
|
105
102
|
export interface PluginUserPageContext extends PluginContext {
|
|
106
|
-
viewer:
|
|
107
|
-
actors: PluginUserPageActor[];
|
|
108
|
-
email: string;
|
|
109
|
-
};
|
|
103
|
+
viewer: User;
|
|
110
104
|
}
|
|
111
105
|
|
|
112
106
|
/** Navigation metadata and reader for one core-rendered plugin user page. */
|