@sentry/junior-plugin-api 0.124.2 → 0.126.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 +23 -8
- package/dist/context.d.ts +6 -2
- package/dist/conversation-events.d.ts +15 -3
- package/dist/dispatch.d.ts +3 -1
- package/dist/index.js +15 -10
- package/dist/operations.d.ts +4 -0
- package/dist/prompt.d.ts +3 -0
- package/dist/schemas.d.ts +24 -15
- package/dist/tasks.d.ts +4 -4
- package/package.json +1 -1
- package/src/context.ts +12 -6
- package/src/conversation-events.ts +23 -6
- package/src/dispatch.ts +3 -0
- package/src/operations.ts +4 -0
- package/src/prompt.ts +3 -0
- package/src/schemas.ts +17 -3
package/README.md
CHANGED
|
@@ -44,9 +44,17 @@ reports, and other typed hook surfaces exported by this package.
|
|
|
44
44
|
database, logging, and only the host capabilities required by that hook.
|
|
45
45
|
- Prompt hooks return bounded structured prompt messages rather than mutate the
|
|
46
46
|
core prompt.
|
|
47
|
+
- User prompt hooks for durable turns may emit registered structured events
|
|
48
|
+
through `ctx.events` for auxiliary work completed while building context.
|
|
47
49
|
- Tool hooks return model-visible schemas aligned with their executor inputs.
|
|
48
50
|
- Host-owned structured model and embedding calls do not expose provider
|
|
49
|
-
credentials to plugins.
|
|
51
|
+
credentials to plugins. Both return a best-effort provider cost estimate when
|
|
52
|
+
one is available.
|
|
53
|
+
- Operational report and authenticated API hooks may aggregate `costUsd` from
|
|
54
|
+
their own registered conversation events through `ctx.eventStats`. Core
|
|
55
|
+
binds the plugin namespace and owns access to the conversation event log.
|
|
56
|
+
Event `costUsd` is additive operation cost and must not duplicate cost
|
|
57
|
+
already recorded in the conversation's agent model usage.
|
|
50
58
|
- Authenticated API route apps receive one verified viewer in their request
|
|
51
59
|
context. The registration hook exposes actor resolution for plugins whose
|
|
52
60
|
viewer-owned data spans platform identities.
|
|
@@ -76,10 +84,14 @@ routing, response validation, rendering, confirmation, and query state.
|
|
|
76
84
|
- Conversation-bound background tasks may emit registered structured events
|
|
77
85
|
through `ctx.events`. Define each version with `defineConversationEvent()`;
|
|
78
86
|
the host supplies the plugin namespace, conversation, turn, ordering, and
|
|
79
|
-
timestamps
|
|
80
|
-
|
|
87
|
+
timestamps without treating background work as new conversation activity.
|
|
88
|
+
Event definitions return bounded transcript presentation data, while Junior
|
|
89
|
+
owns browser rendering.
|
|
81
90
|
- `ctx.agent.dispatch` creates durable agent work with an explicit actor,
|
|
82
91
|
destination, source, metadata, and idempotency identity.
|
|
92
|
+
- Dispatches may include compact `replyAttribution` for destination-visible
|
|
93
|
+
context about what produced the reply. Core owns platform rendering; opaque
|
|
94
|
+
dispatch metadata remains internal.
|
|
83
95
|
- Delegated credential subjects declare the narrow action that authorized them.
|
|
84
96
|
Core owns runtime bindings; scheduler task subjects are accepted only from the
|
|
85
97
|
scheduler plugin and are bound to the exact task id.
|
|
@@ -90,11 +102,14 @@ routing, response validation, rendering, confirmation, and query state.
|
|
|
90
102
|
|
|
91
103
|
Register plugin-owned event definitions through `conversationEvents`. A
|
|
92
104
|
definition owns one local name, version, content schema, and `renderEvent()`
|
|
93
|
-
projection.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
plugin
|
|
97
|
-
|
|
105
|
+
projection. A renderer may return `undefined` when an event should remain
|
|
106
|
+
durable without producing a transcript row. The active plugin context supplies
|
|
107
|
+
the namespace, so plugins cannot emit native events or impersonate another
|
|
108
|
+
plugin. The `junior` plugin name is reserved for host-owned native events.
|
|
109
|
+
Versions of the same event name share one operation idempotency identity,
|
|
110
|
+
so keep previous definitions registered when evolving an event. Stored events
|
|
111
|
+
remain durable when a plugin is removed, but normal transcript projection skips
|
|
112
|
+
definitions that are not currently registered.
|
|
98
113
|
|
|
99
114
|
## Database
|
|
100
115
|
|
package/dist/context.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export type SlackSource = Extract<Source, {
|
|
|
14
14
|
export type LocalSource = Extract<Source, {
|
|
15
15
|
platform: "local";
|
|
16
16
|
}>;
|
|
17
|
-
export type
|
|
17
|
+
export type SourceVisibility = Source["visibility"];
|
|
18
18
|
export type Destination = z.output<typeof destinationSchema>;
|
|
19
19
|
export type SlackDestination = Extract<Destination, {
|
|
20
20
|
platform: "slack";
|
|
@@ -38,6 +38,8 @@ export interface PluginModel {
|
|
|
38
38
|
schema: TSchema;
|
|
39
39
|
system?: string;
|
|
40
40
|
}): Promise<{
|
|
41
|
+
/** Best-effort estimated provider cost for this completion. */
|
|
42
|
+
costUsd?: number;
|
|
41
43
|
object: z.infer<TSchema>;
|
|
42
44
|
}>;
|
|
43
45
|
}
|
|
@@ -46,6 +48,8 @@ export interface PluginEmbedder {
|
|
|
46
48
|
embedTexts(input: {
|
|
47
49
|
texts: string[];
|
|
48
50
|
}): Promise<{
|
|
51
|
+
/** Best-effort estimated provider cost for this embedding call. */
|
|
52
|
+
costUsd?: number;
|
|
49
53
|
dimensions: number;
|
|
50
54
|
model: string;
|
|
51
55
|
provider: string;
|
|
@@ -87,7 +91,7 @@ export declare function createSlackSource(input: {
|
|
|
87
91
|
teamId: string;
|
|
88
92
|
threadTs?: string;
|
|
89
93
|
/** Runtime-normalized source visibility. */
|
|
90
|
-
|
|
94
|
+
visibility: SourceVisibility;
|
|
91
95
|
}): SlackSource;
|
|
92
96
|
/** Build a normalized local source from a local conversation id. */
|
|
93
97
|
export declare function createLocalSource(conversationId: string): LocalSource;
|
|
@@ -39,12 +39,12 @@ export interface PluginConversationEventValue {
|
|
|
39
39
|
readonly data: Record<string, unknown>;
|
|
40
40
|
readonly definition: PluginConversationEventDefinition;
|
|
41
41
|
}
|
|
42
|
-
/** Registered schema and transcript presentation for one
|
|
42
|
+
/** Registered schema and optional transcript presentation for one event version. */
|
|
43
43
|
export interface PluginConversationEventDefinition {
|
|
44
44
|
readonly eventName: string;
|
|
45
45
|
readonly version: number;
|
|
46
46
|
parse(data: unknown): Record<string, unknown>;
|
|
47
|
-
renderEvent(data: Record<string, unknown>): ConversationEventPresentation;
|
|
47
|
+
renderEvent(data: Record<string, unknown>): ConversationEventPresentation | undefined;
|
|
48
48
|
}
|
|
49
49
|
/** Typed factory returned while authoring one plugin conversation event. */
|
|
50
50
|
export interface DefinedConversationEvent<TInput> extends PluginConversationEventDefinition {
|
|
@@ -55,9 +55,21 @@ export declare function defineConversationEvent<TSchema extends z.ZodType<Record
|
|
|
55
55
|
name: string;
|
|
56
56
|
version: number;
|
|
57
57
|
schema: TSchema;
|
|
58
|
-
renderEvent(event: z.output<TSchema>): z.input<typeof conversationEventPresentationSchema
|
|
58
|
+
renderEvent(event: z.output<TSchema>): z.input<typeof conversationEventPresentationSchema> | undefined;
|
|
59
59
|
}): DefinedConversationEvent<z.input<TSchema>>;
|
|
60
60
|
/** Conversation-bound event writer supplied by Junior core. */
|
|
61
61
|
export interface PluginConversationEvents {
|
|
62
62
|
emit(event: PluginConversationEventValue): Promise<void>;
|
|
63
63
|
}
|
|
64
|
+
export interface PluginConversationEventCostDay {
|
|
65
|
+
costUsd: number;
|
|
66
|
+
date: string;
|
|
67
|
+
events: number;
|
|
68
|
+
}
|
|
69
|
+
/** Read aggregate costs for events owned by the current plugin namespace. */
|
|
70
|
+
export interface PluginConversationEventStats {
|
|
71
|
+
costsByDay(input: {
|
|
72
|
+
days: 7 | 30 | 90;
|
|
73
|
+
eventName: string;
|
|
74
|
+
}): Promise<PluginConversationEventCostDay[]>;
|
|
75
|
+
}
|
package/dist/dispatch.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { destinationVisibilitySchema, dispatchOptionsSchema } from "./schemas";
|
|
2
|
+
import { destinationVisibilitySchema, dispatchOptionsSchema, replyAttributionSchema } from "./schemas";
|
|
3
3
|
export type DestinationVisibility = z.output<typeof destinationVisibilitySchema>;
|
|
4
4
|
export type DispatchOptions = z.output<typeof dispatchOptionsSchema>;
|
|
5
|
+
/** Compact destination-visible context explaining what produced a reply. */
|
|
6
|
+
export type ReplyAttribution = z.output<typeof replyAttributionSchema>;
|
|
5
7
|
export interface DispatchResult {
|
|
6
8
|
id: string;
|
|
7
9
|
status: "created" | "already_exists";
|
package/dist/index.js
CHANGED
|
@@ -64,9 +64,8 @@ function defineConversationEvent(definition) {
|
|
|
64
64
|
},
|
|
65
65
|
renderEvent(data) {
|
|
66
66
|
const parsed = definition.schema.parse(data);
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
);
|
|
67
|
+
const presentation = definition.renderEvent(parsed);
|
|
68
|
+
return presentation === void 0 ? void 0 : conversationEventPresentationSchema.parse(presentation);
|
|
70
69
|
}
|
|
71
70
|
});
|
|
72
71
|
return eventDefinition;
|
|
@@ -85,7 +84,7 @@ var exactNonBlankStringSchema = nonBlankStringSchema.refine(
|
|
|
85
84
|
(value) => value === value.trim()
|
|
86
85
|
);
|
|
87
86
|
var platformSchema = z3.enum(["slack", "local"]);
|
|
88
|
-
var
|
|
87
|
+
var sourceVisibilitySchema = z3.enum(["public", "private"]);
|
|
89
88
|
var destinationVisibilitySchema = z3.enum(["public", "private"]);
|
|
90
89
|
var slackAddressSchema = z3.object({
|
|
91
90
|
platform: z3.literal("slack"),
|
|
@@ -102,13 +101,13 @@ var destinationSchema = z3.discriminatedUnion("platform", [
|
|
|
102
101
|
localDestinationSchema
|
|
103
102
|
]);
|
|
104
103
|
var slackSourceSchema = slackAddressSchema.extend({
|
|
105
|
-
|
|
104
|
+
visibility: sourceVisibilitySchema,
|
|
106
105
|
messageTs: nonBlankStringSchema.optional(),
|
|
107
106
|
threadTs: nonBlankStringSchema.optional()
|
|
108
107
|
}).strict();
|
|
109
108
|
var localSourceSchema = z3.object({
|
|
110
109
|
platform: z3.literal("local"),
|
|
111
|
-
|
|
110
|
+
visibility: z3.literal("private"),
|
|
112
111
|
conversationId: localConversationIdSchema
|
|
113
112
|
}).strict();
|
|
114
113
|
var sourceSchema = z3.discriminatedUnion("platform", [
|
|
@@ -203,6 +202,10 @@ var dispatchMetadataSchema = z3.record(z3.string(), z3.string()).superRefine((me
|
|
|
203
202
|
}
|
|
204
203
|
}
|
|
205
204
|
});
|
|
205
|
+
var replyAttributionSchema = z3.object({
|
|
206
|
+
label: exactNonBlankStringSchema.pipe(z3.string().max(48)).refine((value) => !/[\r\n]/.test(value)),
|
|
207
|
+
detail: exactNonBlankStringSchema.pipe(z3.string().max(128)).refine((value) => !/[\r\n]/.test(value)).optional()
|
|
208
|
+
}).strict();
|
|
206
209
|
var dispatchOptionsSchema = z3.object({
|
|
207
210
|
idempotencyKey: nonBlankStringSchema.pipe(z3.string().max(512)),
|
|
208
211
|
credentialSubject: pluginCredentialSubjectSchema.optional(),
|
|
@@ -210,6 +213,7 @@ var dispatchOptionsSchema = z3.object({
|
|
|
210
213
|
destinationVisibility: destinationVisibilitySchema,
|
|
211
214
|
input: nonBlankStringSchema.pipe(z3.string().max(32e3)),
|
|
212
215
|
metadata: dispatchMetadataSchema.optional(),
|
|
216
|
+
replyAttribution: replyAttributionSchema.optional(),
|
|
213
217
|
source: sourceSchema
|
|
214
218
|
}).strict();
|
|
215
219
|
|
|
@@ -217,7 +221,7 @@ var dispatchOptionsSchema = z3.object({
|
|
|
217
221
|
function createSlackSource(input) {
|
|
218
222
|
return {
|
|
219
223
|
platform: "slack",
|
|
220
|
-
|
|
224
|
+
visibility: input.visibility,
|
|
221
225
|
teamId: input.teamId,
|
|
222
226
|
channelId: input.channelId,
|
|
223
227
|
...input.messageTs ? { messageTs: input.messageTs } : {},
|
|
@@ -227,12 +231,12 @@ function createSlackSource(input) {
|
|
|
227
231
|
function createLocalSource(conversationId) {
|
|
228
232
|
return {
|
|
229
233
|
platform: "local",
|
|
230
|
-
|
|
234
|
+
visibility: "private",
|
|
231
235
|
conversationId
|
|
232
236
|
};
|
|
233
237
|
}
|
|
234
238
|
function isPrivateSource(source) {
|
|
235
|
-
return source.
|
|
239
|
+
return source.visibility === "private";
|
|
236
240
|
}
|
|
237
241
|
function getSourceKey(source) {
|
|
238
242
|
if (source.platform === "local") {
|
|
@@ -747,13 +751,14 @@ export {
|
|
|
747
751
|
pluginUserPageLinksSchema,
|
|
748
752
|
promptContextSchema,
|
|
749
753
|
promptMessageSchema,
|
|
754
|
+
replyAttributionSchema,
|
|
750
755
|
resourceEventSchema,
|
|
751
756
|
resourceLinkAnnotationSchema,
|
|
752
757
|
slackActorSchema,
|
|
753
758
|
slackDestinationSchema,
|
|
754
759
|
slackSourceSchema,
|
|
755
760
|
sourceSchema,
|
|
756
|
-
|
|
761
|
+
sourceVisibilitySchema,
|
|
757
762
|
subscribableResourceSchema,
|
|
758
763
|
systemActorSchema,
|
|
759
764
|
toolApprovalModeSchema,
|
package/dist/operations.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { Dispatch, DispatchOptions, DispatchResult } from "./dispatch";
|
|
|
4
4
|
import type { PluginReadState, PluginState } from "./state";
|
|
5
5
|
import type { ResourceEventPublisher } from "./resource-events";
|
|
6
6
|
import type { PluginConversationAnnotations } from "./annotations";
|
|
7
|
+
import type { PluginConversationEventStats } from "./conversation-events";
|
|
7
8
|
export interface HeartbeatHookContext extends PluginContext {
|
|
8
9
|
agent: {
|
|
9
10
|
dispatch(options: DispatchOptions): Promise<DispatchResult>;
|
|
@@ -37,6 +38,7 @@ export interface PluginOperationalRecordSet {
|
|
|
37
38
|
title: string;
|
|
38
39
|
}
|
|
39
40
|
export interface PluginOperationalChartSeries {
|
|
41
|
+
format?: "usd";
|
|
40
42
|
key: string;
|
|
41
43
|
label: string;
|
|
42
44
|
tone?: PluginOperationalTone;
|
|
@@ -67,6 +69,7 @@ export interface PluginOperationalReport extends PluginOperationalReportContent
|
|
|
67
69
|
pluginName: string;
|
|
68
70
|
}
|
|
69
71
|
export interface OperationalReportHookContext extends PluginContext {
|
|
72
|
+
eventStats: PluginConversationEventStats;
|
|
70
73
|
nowMs: number;
|
|
71
74
|
state: PluginReadState;
|
|
72
75
|
}
|
|
@@ -89,6 +92,7 @@ export interface RouteRegistrationHookContext extends PluginContext {
|
|
|
89
92
|
resourceEvents: ResourceEventPublisher;
|
|
90
93
|
}
|
|
91
94
|
export interface ApiRouteRegistrationHookContext extends PluginContext {
|
|
95
|
+
eventStats: PluginConversationEventStats;
|
|
92
96
|
viewer: {
|
|
93
97
|
/** Resolve every runtime actor linked to one authenticated viewer email. */
|
|
94
98
|
actors(email: string): Promise<Array<LocalActor | SlackActor>>;
|
package/dist/prompt.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import type { Destination, Platform, PluginContext, PluginEmbedder, PluginModel, Actor, Source } from "./context";
|
|
3
3
|
import type { PluginState } from "./state";
|
|
4
|
+
import type { PluginConversationEvents } from "./conversation-events";
|
|
4
5
|
export declare const promptMessageSchema: z.ZodObject<{
|
|
5
6
|
text: z.ZodString;
|
|
6
7
|
}, z.core.$strict>;
|
|
@@ -36,6 +37,8 @@ export type UserPromptContext = Pick<PluginContext, "db" | "log" | "plugin"> & {
|
|
|
36
37
|
conversationId?: string;
|
|
37
38
|
destination: Destination;
|
|
38
39
|
embedder: PluginEmbedder;
|
|
40
|
+
/** Conversation-bound event writer when the prompt belongs to a durable turn. */
|
|
41
|
+
events?: PluginConversationEvents;
|
|
39
42
|
model: PluginModel;
|
|
40
43
|
actor?: Actor;
|
|
41
44
|
source: Source;
|
package/dist/schemas.d.ts
CHANGED
|
@@ -6,9 +6,9 @@ export declare const platformSchema: z.ZodEnum<{
|
|
|
6
6
|
local: "local";
|
|
7
7
|
}>;
|
|
8
8
|
/** Runtime source visibility visible to plugins. */
|
|
9
|
-
export declare const
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
export declare const sourceVisibilitySchema: z.ZodEnum<{
|
|
10
|
+
public: "public";
|
|
11
|
+
private: "private";
|
|
12
12
|
}>;
|
|
13
13
|
/** Provider-neutral visibility of a routed destination. */
|
|
14
14
|
export declare const destinationVisibilitySchema: z.ZodEnum<{
|
|
@@ -40,9 +40,9 @@ export declare const slackSourceSchema: z.ZodObject<{
|
|
|
40
40
|
platform: z.ZodLiteral<"slack">;
|
|
41
41
|
teamId: z.ZodString;
|
|
42
42
|
channelId: z.ZodString;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
visibility: z.ZodEnum<{
|
|
44
|
+
public: "public";
|
|
45
|
+
private: "private";
|
|
46
46
|
}>;
|
|
47
47
|
messageTs: z.ZodOptional<z.ZodString>;
|
|
48
48
|
threadTs: z.ZodOptional<z.ZodString>;
|
|
@@ -50,7 +50,7 @@ export declare const slackSourceSchema: z.ZodObject<{
|
|
|
50
50
|
/** Runtime-owned local CLI coordinates for the inbound invocation. */
|
|
51
51
|
export declare const localSourceSchema: z.ZodObject<{
|
|
52
52
|
platform: z.ZodLiteral<"local">;
|
|
53
|
-
|
|
53
|
+
visibility: z.ZodLiteral<"private">;
|
|
54
54
|
conversationId: z.ZodString;
|
|
55
55
|
}, z.core.$strict>;
|
|
56
56
|
/** Runtime-owned provider-neutral coordinates for the inbound invocation. */
|
|
@@ -58,15 +58,15 @@ export declare const sourceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
58
58
|
platform: z.ZodLiteral<"slack">;
|
|
59
59
|
teamId: z.ZodString;
|
|
60
60
|
channelId: z.ZodString;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
visibility: z.ZodEnum<{
|
|
62
|
+
public: "public";
|
|
63
|
+
private: "private";
|
|
64
64
|
}>;
|
|
65
65
|
messageTs: z.ZodOptional<z.ZodString>;
|
|
66
66
|
threadTs: z.ZodOptional<z.ZodString>;
|
|
67
67
|
}, z.core.$strict>, z.ZodObject<{
|
|
68
68
|
platform: z.ZodLiteral<"local">;
|
|
69
|
-
|
|
69
|
+
visibility: z.ZodLiteral<"private">;
|
|
70
70
|
conversationId: z.ZodString;
|
|
71
71
|
}, z.core.$strict>], "platform">;
|
|
72
72
|
/** Stable user credential subject shape accepted from plugins. */
|
|
@@ -117,6 +117,11 @@ 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
|
+
/** Compact destination-visible context explaining what produced a reply. */
|
|
121
|
+
export declare const replyAttributionSchema: z.ZodObject<{
|
|
122
|
+
label: z.ZodPipe<z.ZodString, z.ZodString>;
|
|
123
|
+
detail: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodString>>;
|
|
124
|
+
}, z.core.$strict>;
|
|
120
125
|
/** Plugin dispatch request accepted by Junior core. */
|
|
121
126
|
export declare const dispatchOptionsSchema: z.ZodObject<{
|
|
122
127
|
idempotencyKey: z.ZodPipe<z.ZodString, z.ZodString>;
|
|
@@ -141,19 +146,23 @@ export declare const dispatchOptionsSchema: z.ZodObject<{
|
|
|
141
146
|
}>;
|
|
142
147
|
input: z.ZodPipe<z.ZodString, z.ZodString>;
|
|
143
148
|
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
149
|
+
replyAttribution: z.ZodOptional<z.ZodObject<{
|
|
150
|
+
label: z.ZodPipe<z.ZodString, z.ZodString>;
|
|
151
|
+
detail: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodString>>;
|
|
152
|
+
}, z.core.$strict>>;
|
|
144
153
|
source: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
145
154
|
platform: z.ZodLiteral<"slack">;
|
|
146
155
|
teamId: z.ZodString;
|
|
147
156
|
channelId: z.ZodString;
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
157
|
+
visibility: z.ZodEnum<{
|
|
158
|
+
public: "public";
|
|
159
|
+
private: "private";
|
|
151
160
|
}>;
|
|
152
161
|
messageTs: z.ZodOptional<z.ZodString>;
|
|
153
162
|
threadTs: z.ZodOptional<z.ZodString>;
|
|
154
163
|
}, z.core.$strict>, z.ZodObject<{
|
|
155
164
|
platform: z.ZodLiteral<"local">;
|
|
156
|
-
|
|
165
|
+
visibility: z.ZodLiteral<"private">;
|
|
157
166
|
conversationId: z.ZodString;
|
|
158
167
|
}, z.core.$strict>], "platform">;
|
|
159
168
|
}, z.core.$strict>;
|
package/dist/tasks.d.ts
CHANGED
|
@@ -126,15 +126,15 @@ export declare const pluginRunContextSchema: z.ZodObject<{
|
|
|
126
126
|
platform: z.ZodLiteral<"slack">;
|
|
127
127
|
teamId: z.ZodString;
|
|
128
128
|
channelId: z.ZodString;
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
visibility: z.ZodEnum<{
|
|
130
|
+
public: "public";
|
|
131
|
+
private: "private";
|
|
132
132
|
}>;
|
|
133
133
|
messageTs: z.ZodOptional<z.ZodString>;
|
|
134
134
|
threadTs: z.ZodOptional<z.ZodString>;
|
|
135
135
|
}, z.core.$strict>, z.ZodObject<{
|
|
136
136
|
platform: z.ZodLiteral<"local">;
|
|
137
|
-
|
|
137
|
+
visibility: z.ZodLiteral<"private">;
|
|
138
138
|
conversationId: z.ZodString;
|
|
139
139
|
}, z.core.$strict>], "platform">;
|
|
140
140
|
transcript: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
package/package.json
CHANGED
package/src/context.ts
CHANGED
|
@@ -19,7 +19,7 @@ export type SystemActor = z.output<typeof systemActorSchema>;
|
|
|
19
19
|
export type Source = z.output<typeof sourceSchema>;
|
|
20
20
|
export type SlackSource = Extract<Source, { platform: "slack" }>;
|
|
21
21
|
export type LocalSource = Extract<Source, { platform: "local" }>;
|
|
22
|
-
export type
|
|
22
|
+
export type SourceVisibility = Source["visibility"];
|
|
23
23
|
|
|
24
24
|
export type Destination = z.output<typeof destinationSchema>;
|
|
25
25
|
|
|
@@ -44,12 +44,18 @@ export interface PluginModel {
|
|
|
44
44
|
prompt: string;
|
|
45
45
|
schema: TSchema;
|
|
46
46
|
system?: string;
|
|
47
|
-
}): Promise<{
|
|
47
|
+
}): Promise<{
|
|
48
|
+
/** Best-effort estimated provider cost for this completion. */
|
|
49
|
+
costUsd?: number;
|
|
50
|
+
object: z.infer<TSchema>;
|
|
51
|
+
}>;
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
export interface PluginEmbedder {
|
|
51
55
|
/** Embed plugin-owned text for derived retrieval without exposing provider credentials. */
|
|
52
56
|
embedTexts(input: { texts: string[] }): Promise<{
|
|
57
|
+
/** Best-effort estimated provider cost for this embedding call. */
|
|
58
|
+
costUsd?: number;
|
|
53
59
|
dimensions: number;
|
|
54
60
|
model: string;
|
|
55
61
|
provider: string;
|
|
@@ -97,11 +103,11 @@ export function createSlackSource(input: {
|
|
|
97
103
|
teamId: string;
|
|
98
104
|
threadTs?: string;
|
|
99
105
|
/** Runtime-normalized source visibility. */
|
|
100
|
-
|
|
106
|
+
visibility: SourceVisibility;
|
|
101
107
|
}): SlackSource {
|
|
102
108
|
return {
|
|
103
109
|
platform: "slack",
|
|
104
|
-
|
|
110
|
+
visibility: input.visibility,
|
|
105
111
|
teamId: input.teamId,
|
|
106
112
|
channelId: input.channelId,
|
|
107
113
|
...(input.messageTs ? { messageTs: input.messageTs } : {}),
|
|
@@ -113,14 +119,14 @@ export function createSlackSource(input: {
|
|
|
113
119
|
export function createLocalSource(conversationId: string): LocalSource {
|
|
114
120
|
return {
|
|
115
121
|
platform: "local",
|
|
116
|
-
|
|
122
|
+
visibility: "private",
|
|
117
123
|
conversationId,
|
|
118
124
|
};
|
|
119
125
|
}
|
|
120
126
|
|
|
121
127
|
/** Return whether a source is private to a person or restricted group. */
|
|
122
128
|
export function isPrivateSource(source: Source): boolean {
|
|
123
|
-
return source.
|
|
129
|
+
return source.visibility === "private";
|
|
124
130
|
}
|
|
125
131
|
|
|
126
132
|
/** Return the stable source identity used for idempotency and attribution. */
|
|
@@ -48,12 +48,14 @@ export interface PluginConversationEventValue {
|
|
|
48
48
|
readonly definition: PluginConversationEventDefinition;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
/** Registered schema and transcript presentation for one
|
|
51
|
+
/** Registered schema and optional transcript presentation for one event version. */
|
|
52
52
|
export interface PluginConversationEventDefinition {
|
|
53
53
|
readonly eventName: string;
|
|
54
54
|
readonly version: number;
|
|
55
55
|
parse(data: unknown): Record<string, unknown>;
|
|
56
|
-
renderEvent(
|
|
56
|
+
renderEvent(
|
|
57
|
+
data: Record<string, unknown>,
|
|
58
|
+
): ConversationEventPresentation | undefined;
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
/** Typed factory returned while authoring one plugin conversation event. */
|
|
@@ -72,7 +74,7 @@ export function defineConversationEvent<
|
|
|
72
74
|
schema: TSchema;
|
|
73
75
|
renderEvent(
|
|
74
76
|
event: z.output<TSchema>,
|
|
75
|
-
): z.input<typeof conversationEventPresentationSchema
|
|
77
|
+
): z.input<typeof conversationEventPresentationSchema> | undefined;
|
|
76
78
|
}): DefinedConversationEvent<z.input<TSchema>> {
|
|
77
79
|
const identity = z
|
|
78
80
|
.object({
|
|
@@ -96,9 +98,10 @@ export function defineConversationEvent<
|
|
|
96
98
|
},
|
|
97
99
|
renderEvent(data: Record<string, unknown>) {
|
|
98
100
|
const parsed = definition.schema.parse(data);
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
const presentation = definition.renderEvent(parsed);
|
|
102
|
+
return presentation === undefined
|
|
103
|
+
? undefined
|
|
104
|
+
: conversationEventPresentationSchema.parse(presentation);
|
|
102
105
|
},
|
|
103
106
|
});
|
|
104
107
|
return eventDefinition;
|
|
@@ -108,3 +111,17 @@ export function defineConversationEvent<
|
|
|
108
111
|
export interface PluginConversationEvents {
|
|
109
112
|
emit(event: PluginConversationEventValue): Promise<void>;
|
|
110
113
|
}
|
|
114
|
+
|
|
115
|
+
export interface PluginConversationEventCostDay {
|
|
116
|
+
costUsd: number;
|
|
117
|
+
date: string;
|
|
118
|
+
events: number;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** Read aggregate costs for events owned by the current plugin namespace. */
|
|
122
|
+
export interface PluginConversationEventStats {
|
|
123
|
+
costsByDay(input: {
|
|
124
|
+
days: 7 | 30 | 90;
|
|
125
|
+
eventName: string;
|
|
126
|
+
}): Promise<PluginConversationEventCostDay[]>;
|
|
127
|
+
}
|
package/src/dispatch.ts
CHANGED
|
@@ -2,12 +2,15 @@ import { z } from "zod";
|
|
|
2
2
|
import {
|
|
3
3
|
destinationVisibilitySchema,
|
|
4
4
|
dispatchOptionsSchema,
|
|
5
|
+
replyAttributionSchema,
|
|
5
6
|
} from "./schemas";
|
|
6
7
|
|
|
7
8
|
export type DestinationVisibility = z.output<
|
|
8
9
|
typeof destinationVisibilitySchema
|
|
9
10
|
>;
|
|
10
11
|
export type DispatchOptions = z.output<typeof dispatchOptionsSchema>;
|
|
12
|
+
/** Compact destination-visible context explaining what produced a reply. */
|
|
13
|
+
export type ReplyAttribution = z.output<typeof replyAttributionSchema>;
|
|
11
14
|
|
|
12
15
|
export interface DispatchResult {
|
|
13
16
|
id: string;
|
package/src/operations.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { nonBlankStringSchema } from "./schemas";
|
|
|
5
5
|
import type { PluginReadState, PluginState } from "./state";
|
|
6
6
|
import type { ResourceEventPublisher } from "./resource-events";
|
|
7
7
|
import type { PluginConversationAnnotations } from "./annotations";
|
|
8
|
+
import type { PluginConversationEventStats } from "./conversation-events";
|
|
8
9
|
|
|
9
10
|
export interface HeartbeatHookContext extends PluginContext {
|
|
10
11
|
agent: {
|
|
@@ -46,6 +47,7 @@ export interface PluginOperationalRecordSet {
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
export interface PluginOperationalChartSeries {
|
|
50
|
+
format?: "usd";
|
|
49
51
|
key: string;
|
|
50
52
|
label: string;
|
|
51
53
|
tone?: PluginOperationalTone;
|
|
@@ -81,6 +83,7 @@ export interface PluginOperationalReport extends PluginOperationalReportContent
|
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
export interface OperationalReportHookContext extends PluginContext {
|
|
86
|
+
eventStats: PluginConversationEventStats;
|
|
84
87
|
nowMs: number;
|
|
85
88
|
state: PluginReadState;
|
|
86
89
|
}
|
|
@@ -120,6 +123,7 @@ export interface RouteRegistrationHookContext extends PluginContext {
|
|
|
120
123
|
}
|
|
121
124
|
|
|
122
125
|
export interface ApiRouteRegistrationHookContext extends PluginContext {
|
|
126
|
+
eventStats: PluginConversationEventStats;
|
|
123
127
|
viewer: {
|
|
124
128
|
/** Resolve every runtime actor linked to one authenticated viewer email. */
|
|
125
129
|
actors(email: string): Promise<Array<LocalActor | SlackActor>>;
|
package/src/prompt.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
Source,
|
|
10
10
|
} from "./context";
|
|
11
11
|
import type { PluginState } from "./state";
|
|
12
|
+
import type { PluginConversationEvents } from "./conversation-events";
|
|
12
13
|
|
|
13
14
|
const promptContextKindSchema = z
|
|
14
15
|
.string()
|
|
@@ -80,6 +81,8 @@ export type UserPromptContext = Pick<PluginContext, "db" | "log" | "plugin"> & {
|
|
|
80
81
|
conversationId?: string;
|
|
81
82
|
destination: Destination;
|
|
82
83
|
embedder: PluginEmbedder;
|
|
84
|
+
/** Conversation-bound event writer when the prompt belongs to a durable turn. */
|
|
85
|
+
events?: PluginConversationEvents;
|
|
83
86
|
model: PluginModel;
|
|
84
87
|
actor?: Actor;
|
|
85
88
|
source: Source;
|
package/src/schemas.ts
CHANGED
|
@@ -23,7 +23,7 @@ const exactNonBlankStringSchema = nonBlankStringSchema.refine(
|
|
|
23
23
|
export const platformSchema = z.enum(["slack", "local"]);
|
|
24
24
|
|
|
25
25
|
/** Runtime source visibility visible to plugins. */
|
|
26
|
-
export const
|
|
26
|
+
export const sourceVisibilitySchema = z.enum(["public", "private"]);
|
|
27
27
|
|
|
28
28
|
/** Provider-neutral visibility of a routed destination. */
|
|
29
29
|
export const destinationVisibilitySchema = z.enum(["public", "private"]);
|
|
@@ -56,7 +56,7 @@ export const destinationSchema = z.discriminatedUnion("platform", [
|
|
|
56
56
|
/** Runtime-owned Slack coordinates for the inbound invocation. */
|
|
57
57
|
export const slackSourceSchema = slackAddressSchema
|
|
58
58
|
.extend({
|
|
59
|
-
|
|
59
|
+
visibility: sourceVisibilitySchema,
|
|
60
60
|
messageTs: nonBlankStringSchema.optional(),
|
|
61
61
|
threadTs: nonBlankStringSchema.optional(),
|
|
62
62
|
})
|
|
@@ -66,7 +66,7 @@ export const slackSourceSchema = slackAddressSchema
|
|
|
66
66
|
export const localSourceSchema = z
|
|
67
67
|
.object({
|
|
68
68
|
platform: z.literal("local"),
|
|
69
|
-
|
|
69
|
+
visibility: z.literal("private"),
|
|
70
70
|
conversationId: localConversationIdSchema,
|
|
71
71
|
})
|
|
72
72
|
.strict();
|
|
@@ -187,6 +187,19 @@ const dispatchMetadataSchema = z
|
|
|
187
187
|
}
|
|
188
188
|
});
|
|
189
189
|
|
|
190
|
+
/** Compact destination-visible context explaining what produced a reply. */
|
|
191
|
+
export const replyAttributionSchema = z
|
|
192
|
+
.object({
|
|
193
|
+
label: exactNonBlankStringSchema
|
|
194
|
+
.pipe(z.string().max(48))
|
|
195
|
+
.refine((value) => !/[\r\n]/.test(value)),
|
|
196
|
+
detail: exactNonBlankStringSchema
|
|
197
|
+
.pipe(z.string().max(128))
|
|
198
|
+
.refine((value) => !/[\r\n]/.test(value))
|
|
199
|
+
.optional(),
|
|
200
|
+
})
|
|
201
|
+
.strict();
|
|
202
|
+
|
|
190
203
|
/** Plugin dispatch request accepted by Junior core. */
|
|
191
204
|
export const dispatchOptionsSchema = z
|
|
192
205
|
.object({
|
|
@@ -196,6 +209,7 @@ export const dispatchOptionsSchema = z
|
|
|
196
209
|
destinationVisibility: destinationVisibilitySchema,
|
|
197
210
|
input: nonBlankStringSchema.pipe(z.string().max(32_000)),
|
|
198
211
|
metadata: dispatchMetadataSchema.optional(),
|
|
212
|
+
replyAttribution: replyAttributionSchema.optional(),
|
|
199
213
|
source: sourceSchema,
|
|
200
214
|
})
|
|
201
215
|
.strict();
|