@sentry/junior-plugin-api 0.124.1 → 0.125.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 +20 -8
- package/dist/context.d.ts +4 -0
- package/dist/conversation-events.d.ts +15 -3
- package/dist/index.js +2 -3
- package/dist/operations.d.ts +4 -0
- package/dist/prompt.d.ts +3 -0
- package/package.json +1 -1
- package/src/context.ts +7 -1
- package/src/conversation-events.ts +23 -6
- package/src/operations.ts +4 -0
- package/src/prompt.ts +3 -0
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,8 +84,9 @@ 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.
|
|
83
92
|
- Delegated credential subjects declare the narrow action that authorized them.
|
|
@@ -90,11 +99,14 @@ routing, response validation, rendering, confirmation, and query state.
|
|
|
90
99
|
|
|
91
100
|
Register plugin-owned event definitions through `conversationEvents`. A
|
|
92
101
|
definition owns one local name, version, content schema, and `renderEvent()`
|
|
93
|
-
projection.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
plugin
|
|
97
|
-
|
|
102
|
+
projection. A renderer may return `undefined` when an event should remain
|
|
103
|
+
durable without producing a transcript row. The active plugin context supplies
|
|
104
|
+
the namespace, so plugins cannot emit native events or impersonate another
|
|
105
|
+
plugin. The `junior` plugin name is reserved for host-owned native events.
|
|
106
|
+
Versions of the same event name share one operation idempotency identity,
|
|
107
|
+
so keep previous definitions registered when evolving an event. Stored events
|
|
108
|
+
remain durable when a plugin is removed, but normal transcript projection skips
|
|
109
|
+
definitions that are not currently registered.
|
|
98
110
|
|
|
99
111
|
## Database
|
|
100
112
|
|
package/dist/context.d.ts
CHANGED
|
@@ -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;
|
|
@@ -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/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;
|
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/package.json
CHANGED
package/src/context.ts
CHANGED
|
@@ -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;
|
|
@@ -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/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;
|