@nettee/beacon 0.4.2 → 0.4.3

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 CHANGED
@@ -68,7 +68,8 @@ and lists the missing paths. Both pairs may exist; the workspace pair wins.
68
68
 
69
69
  Beacon prepends an English platform template for this Run: workspace limit,
70
70
  inbound vs Schedule vs event vs manual capabilities, the `reply_text` / `reply_card` /
71
- `no_reply` / `notify_card` contract, and an optional `submit_feedback` tool.
71
+ `no_reply` / `notify_card` contract, optional `submit_feedback` (instruction gaps),
72
+ and optional `submit_observability_feedback` (RCA observability gaps).
72
73
 
73
74
  Protect the home and secret file before running Beacon:
74
75
 
@@ -1,5 +1,5 @@
1
1
  import type { RunRow } from "@nettee/beacon-shared";
2
- import type { FeedbackRecord } from "../domain/types.js";
2
+ import type { FeedbackRecord, ObservabilityFeedbackRecord } from "../domain/types.js";
3
3
  export declare const runIdPattern: RegExp;
4
4
  export type RunSummary = {
5
5
  profileId: string;
@@ -18,6 +18,7 @@ export type RunSummary = {
18
18
  hasSessionFile: boolean;
19
19
  systemPrompt: string | undefined;
20
20
  feedback: FeedbackRecord | undefined;
21
+ observabilityFeedback: ObservabilityFeedbackRecord | undefined;
21
22
  };
22
23
  export declare function listRunSummaries(profilesDirectory: string): Promise<RunSummary[]>;
23
24
  export declare function kindLabel(row: Pick<RunSummary, "kind" | "scheduleId" | "eventSource" | "eventType">): string;
@@ -1,6 +1,6 @@
1
1
  import { readdir, readFile } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
- import { feedbackRecordSchema } from "../outcome/content.js";
3
+ import { feedbackRecordSchema, observabilityFeedbackRecordSchema, } from "../outcome/content.js";
4
4
  export const runIdPattern = /^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/;
5
5
  function asRecord(value) {
6
6
  return typeof value === "object" && value !== null
@@ -14,6 +14,10 @@ function asFeedback(value) {
14
14
  const parsed = feedbackRecordSchema.safeParse(value);
15
15
  return parsed.success ? parsed.data : undefined;
16
16
  }
17
+ function asObservabilityFeedback(value) {
18
+ const parsed = observabilityFeedbackRecordSchema.safeParse(value);
19
+ return parsed.success ? parsed.data : undefined;
20
+ }
17
21
  async function readDirents(path) {
18
22
  try {
19
23
  return await readdir(path, { withFileTypes: true });
@@ -61,6 +65,7 @@ function summarize(value, hasSessionFile) {
61
65
  hasSessionFile,
62
66
  systemPrompt: asString(run?.systemPrompt),
63
67
  feedback: asFeedback(record.feedback),
68
+ observabilityFeedback: asObservabilityFeedback(record.observabilityFeedback),
64
69
  };
65
70
  }
66
71
  async function loadSummary(path) {
@@ -126,6 +131,12 @@ export function toRunListItem(row) {
126
131
  summary: item.summary,
127
132
  }))
128
133
  : null,
134
+ observabilityFeedback: row.observabilityFeedback && row.observabilityFeedback.items.length > 0
135
+ ? row.observabilityFeedback.items.map((item) => ({
136
+ priority: item.priority,
137
+ summary: item.summary,
138
+ }))
139
+ : null,
129
140
  };
130
141
  }
131
142
  export async function findRunSummary(profilesDirectory, runId) {
@@ -84,6 +84,20 @@ export type FeedbackRecord = {
84
84
  items: FeedbackItem[];
85
85
  submittedAt: string;
86
86
  };
87
+ /** Observability-gap feedback may include low; instruction feedback may not. */
88
+ export declare const observabilityFeedbackPriorities: readonly ["high", "medium", "low"];
89
+ export type ObservabilityFeedbackPriority = (typeof observabilityFeedbackPriorities)[number];
90
+ export type ObservabilityFeedbackItem = {
91
+ priority: ObservabilityFeedbackPriority;
92
+ summary: string;
93
+ };
94
+ export type ObservabilityFeedbackContent = {
95
+ items: ObservabilityFeedbackItem[];
96
+ };
97
+ export type ObservabilityFeedbackRecord = {
98
+ items: ObservabilityFeedbackItem[];
99
+ submittedAt: string;
100
+ };
87
101
  export type DeliveryContent = TextReplyContent | CardContent;
88
102
  export type RunRecord = {
89
103
  runId: string;
@@ -132,6 +146,8 @@ export type TriggerRecord = {
132
146
  finalOutcome?: FinalOutcomeRecord | undefined;
133
147
  /** Present only when the Agent called `submit_feedback`. */
134
148
  feedback?: FeedbackRecord | undefined;
149
+ /** Present only when the Agent called `submit_observability_feedback`. */
150
+ observabilityFeedback?: ObservabilityFeedbackRecord | undefined;
135
151
  delivery?: DeliveryRecord | undefined;
136
152
  notifyDelivery?: DeliveryRecord | undefined;
137
153
  };
@@ -17,3 +17,9 @@ export const failureCodes = [
17
17
  "delivery_interrupted",
18
18
  ];
19
19
  export const feedbackPriorities = ["high", "medium"];
20
+ /** Observability-gap feedback may include low; instruction feedback may not. */
21
+ export const observabilityFeedbackPriorities = [
22
+ "high",
23
+ "medium",
24
+ "low",
25
+ ];
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import type { CardContent, DeliveryContent, FeedbackContent, FinalOutcomeContent, ReplyContent } from "../domain/types.js";
2
+ import type { CardContent, DeliveryContent, FeedbackContent, FinalOutcomeContent, ObservabilityFeedbackContent, ReplyContent } from "../domain/types.js";
3
3
  export declare const feedbackItemSchema: z.ZodObject<{
4
4
  priority: z.ZodEnum<{
5
5
  high: "high";
@@ -26,6 +26,35 @@ export declare const feedbackRecordSchema: z.ZodObject<{
26
26
  }, z.core.$strict>>;
27
27
  submittedAt: z.ZodString;
28
28
  }, z.core.$strict>;
29
+ export declare const observabilityFeedbackItemSchema: z.ZodObject<{
30
+ priority: z.ZodEnum<{
31
+ high: "high";
32
+ medium: "medium";
33
+ low: "low";
34
+ }>;
35
+ summary: z.ZodString;
36
+ }, z.core.$strict>;
37
+ export declare const observabilityFeedbackContentSchema: z.ZodObject<{
38
+ items: z.ZodArray<z.ZodObject<{
39
+ priority: z.ZodEnum<{
40
+ high: "high";
41
+ medium: "medium";
42
+ low: "low";
43
+ }>;
44
+ summary: z.ZodString;
45
+ }, z.core.$strict>>;
46
+ }, z.core.$strict>;
47
+ export declare const observabilityFeedbackRecordSchema: z.ZodObject<{
48
+ items: z.ZodArray<z.ZodObject<{
49
+ priority: z.ZodEnum<{
50
+ high: "high";
51
+ medium: "medium";
52
+ low: "low";
53
+ }>;
54
+ summary: z.ZodString;
55
+ }, z.core.$strict>>;
56
+ submittedAt: z.ZodString;
57
+ }, z.core.$strict>;
29
58
  export declare const finalOutcomeContentSchema: z.ZodObject<{
30
59
  reply: z.ZodDiscriminatedUnion<[z.ZodObject<{
31
60
  kind: z.ZodLiteral<"text">;
@@ -56,6 +85,7 @@ export type OutcomePatch = {
56
85
  reply?: ReplyContent | undefined;
57
86
  notify?: CardContent | undefined;
58
87
  feedback?: FeedbackContent | undefined;
88
+ observabilityFeedback?: ObservabilityFeedbackContent | undefined;
59
89
  };
60
90
  export declare function parseFinalOutcomeContent(value: unknown): FinalOutcomeContent;
61
91
  export declare function parseOutcomePatch(value: unknown): OutcomePatch;
@@ -46,6 +46,23 @@ export const feedbackRecordSchema = z
46
46
  submittedAt: z.string().datetime({ offset: true }),
47
47
  })
48
48
  .strict();
49
+ export const observabilityFeedbackItemSchema = z
50
+ .object({
51
+ priority: z.enum(["high", "medium", "low"]),
52
+ summary: nonBlank.max(1024),
53
+ })
54
+ .strict();
55
+ export const observabilityFeedbackContentSchema = z
56
+ .object({
57
+ items: z.array(observabilityFeedbackItemSchema).min(1).max(3),
58
+ })
59
+ .strict();
60
+ export const observabilityFeedbackRecordSchema = z
61
+ .object({
62
+ items: z.array(observabilityFeedbackItemSchema).min(1).max(3),
63
+ submittedAt: z.string().datetime({ offset: true }),
64
+ })
65
+ .strict();
49
66
  export const finalOutcomeContentSchema = z
50
67
  .object({
51
68
  reply: replySchema,
@@ -57,12 +74,14 @@ const outcomePatchSchema = z
57
74
  reply: replySchema.optional(),
58
75
  notify: cardSchema.optional(),
59
76
  feedback: feedbackContentSchema.optional(),
77
+ observabilityFeedback: observabilityFeedbackContentSchema.optional(),
60
78
  })
61
79
  .strict()
62
80
  .refine((value) => value.reply !== undefined ||
63
81
  value.notify !== undefined ||
64
- value.feedback !== undefined, {
65
- message: "Outcome submission must include reply, notify, or feedback",
82
+ value.feedback !== undefined ||
83
+ value.observabilityFeedback !== undefined, {
84
+ message: "Outcome submission must include reply, notify, feedback, or observabilityFeedback",
66
85
  });
67
86
  const legacyOutcomeSchema = z.discriminatedUnion("kind", [
68
87
  textReplySchema,
@@ -106,6 +125,9 @@ export function mergeOutcome(current, patch) {
106
125
  if (patch.feedback && current?.feedback) {
107
126
  throw new Error("Feedback already submitted");
108
127
  }
128
+ if (patch.observabilityFeedback && current?.observabilityFeedback) {
129
+ throw new Error("Observability feedback already submitted");
130
+ }
109
131
  return {
110
132
  ...(current?.reply || patch.reply
111
133
  ? { reply: patch.reply ?? current?.reply }
@@ -116,6 +138,11 @@ export function mergeOutcome(current, patch) {
116
138
  ...(current?.feedback || patch.feedback
117
139
  ? { feedback: patch.feedback ?? current?.feedback }
118
140
  : {}),
141
+ ...(current?.observabilityFeedback || patch.observabilityFeedback
142
+ ? {
143
+ observabilityFeedback: patch.observabilityFeedback ?? current?.observabilityFeedback,
144
+ }
145
+ : {}),
119
146
  };
120
147
  }
121
148
  /** Stable English summary when the Agent settles without closing reply/no_reply. */
@@ -1,3 +1,4 @@
1
1
  export declare const inboundOutOfRoleReply = "\u8FD9\u6761\u6D88\u606F\u4E0D\u5728\u6211\u7684\u804C\u8D23\u8303\u56F4\u5185\u3002";
2
2
  export declare const finalOutcomeContractInstructions: readonly ["`reply_text` sends plain text. For an inbound Feishu message, quote-reply that message. For a Schedule, message the Profile admin. For a manual Run, print to the operator. Do not fill `chat_id`.", "`reply_card` sends a titled Markdown card on the conversational channel (inbound quote-reply, or Schedule admin chat). It closes that channel by itself. Do not also call `reply_text` or `no_reply` on the same Run. Do not fill `chat_id`.", "`no_reply` finishes a Run without messaging the conversational channel. Its reason is stored for audit and is never sent. Do not use it on inbound Feishu messages.", "`notify_card` posts a titled Markdown card to this Run's configured notify group. Call it only when this Run has a notify target. Do not fill `chat_id`.", "Which tool to use for a given business result is decided by the Profile persona/task (or the situation), not by these platform lines alone.", "Beacon ignores ordinary assistant final text for Delivery."];
3
- export declare const feedbackContractInstructions: readonly ["If this Run had a real high or medium problem with instructions, Skills, dependencies, or tools, you may call `submit_feedback` once with one to three items.", "If there are none, do not call it. Do not invent items. Do not report low-priority issues, taste, or problems you already worked around without needing a platform change."];
3
+ export declare const feedbackContractInstructions: readonly ["If this Run had a real high or medium problem with instructions, Skills, dependencies, or tools, you may call `submit_feedback` once with one to three items.", "If there are none, do not call it. Do not invent items. Do not report low-priority issues, taste, or problems you already worked around without needing a platform change.", "Do not put observability gaps in `submit_feedback`. Use `submit_observability_feedback` for those."];
4
+ export declare const observabilityFeedbackContractInstructions: readonly ["If root-cause analysis on this Run was held back by missing observability (logs, metrics, traces, event correlation, or similar signals), you may call `submit_observability_feedback` once with one to three items at high, medium, or low priority.", "Say what signal is missing and how adding it would make RCA more useful or more certain. If there are none, do not call it. Do not invent items.", "Do not put instruction, Skill, dependency, or tool problems in `submit_observability_feedback`. Use `submit_feedback` for those."];
@@ -10,4 +10,10 @@ export const finalOutcomeContractInstructions = [
10
10
  export const feedbackContractInstructions = [
11
11
  "If this Run had a real high or medium problem with instructions, Skills, dependencies, or tools, you may call `submit_feedback` once with one to three items.",
12
12
  "If there are none, do not call it. Do not invent items. Do not report low-priority issues, taste, or problems you already worked around without needing a platform change.",
13
+ "Do not put observability gaps in `submit_feedback`. Use `submit_observability_feedback` for those.",
14
+ ];
15
+ export const observabilityFeedbackContractInstructions = [
16
+ "If root-cause analysis on this Run was held back by missing observability (logs, metrics, traces, event correlation, or similar signals), you may call `submit_observability_feedback` once with one to three items at high, medium, or low priority.",
17
+ "Say what signal is missing and how adding it would make RCA more useful or more certain. If there are none, do not call it. Do not invent items.",
18
+ "Do not put instruction, Skill, dependency, or tool problems in `submit_observability_feedback`. Use `submit_feedback` for those.",
13
19
  ];
@@ -1,4 +1,4 @@
1
- import type { FeedbackRecord, FinalOutcomeContent } from "../domain/types.js";
1
+ import type { FeedbackRecord, FinalOutcomeContent, ObservabilityFeedbackRecord } from "../domain/types.js";
2
2
  export type OutcomeBinding = {
3
3
  socketPath: string;
4
4
  runToken: string;
@@ -7,6 +7,7 @@ export type OutcomeSubmission = {
7
7
  binding: OutcomeBinding;
8
8
  take(): FinalOutcomeContent;
9
9
  takeFeedback(): FeedbackRecord | undefined;
10
+ takeObservabilityFeedback(): ObservabilityFeedbackRecord | undefined;
10
11
  cancel(): void;
11
12
  };
12
13
  export type OutcomeSink = {
@@ -76,6 +76,10 @@ export async function startOutcomeServer(options = {}) {
76
76
  if (patch.feedback && !previous?.feedback) {
77
77
  submission.feedbackSubmittedAt = new Date().toISOString();
78
78
  }
79
+ if (patch.observabilityFeedback && !previous?.observabilityFeedback) {
80
+ submission.observabilityFeedbackSubmittedAt =
81
+ new Date().toISOString();
82
+ }
79
83
  }
80
84
  catch (error) {
81
85
  respond(socket, {
@@ -113,6 +117,16 @@ export async function startOutcomeServer(options = {}) {
113
117
  }
114
118
  return { items, submittedAt: record.feedbackSubmittedAt };
115
119
  },
120
+ takeObservabilityFeedback() {
121
+ const items = record.outcome?.observabilityFeedback?.items;
122
+ if (!items || record.observabilityFeedbackSubmittedAt === undefined) {
123
+ return undefined;
124
+ }
125
+ return {
126
+ items,
127
+ submittedAt: record.observabilityFeedbackSubmittedAt,
128
+ };
129
+ },
116
130
  cancel() {
117
131
  submissions.delete(runToken);
118
132
  },
@@ -253,7 +253,7 @@ export class RunOrchestrator {
253
253
  await this.deliverField(triggerKey, "notifyDelivery", current.notifyTarget, outcome.notify, create && current.notifyDelivery === undefined);
254
254
  }
255
255
  }
256
- async fail(triggerKey, runId, code, error, submitted, settle) {
256
+ async fail(triggerKey, runId, code, error, submitted, submittedObservability, settle) {
257
257
  let detail = isMissingReplyOutcomeError(error)
258
258
  ? MISSING_REPLY_OUTCOME_SUMMARY
259
259
  : summary(error);
@@ -278,6 +278,9 @@ export class RunOrchestrator {
278
278
  submittedAt: this.timestamp(),
279
279
  },
280
280
  ...(submitted ? { feedback: submitted } : {}),
281
+ ...(submittedObservability
282
+ ? { observabilityFeedback: submittedObservability }
283
+ : {}),
281
284
  }));
282
285
  await this.deliverOutcome(triggerKey);
283
286
  }
@@ -336,6 +339,7 @@ export class RunOrchestrator {
336
339
  text: completion.text,
337
340
  };
338
341
  const submitted = submission.takeFeedback();
342
+ const submittedObservability = submission.takeObservabilityFeedback();
339
343
  const outcome = normalizeAgentOutcome(input, submission.take(), record.notifyTarget);
340
344
  await this.options.store.update(triggerKey, (current) => ({
341
345
  ...current,
@@ -352,18 +356,22 @@ export class RunOrchestrator {
352
356
  submittedAt: this.timestamp(),
353
357
  },
354
358
  ...(submitted ? { feedback: submitted } : {}),
359
+ ...(submittedObservability
360
+ ? { observabilityFeedback: submittedObservability }
361
+ : {}),
355
362
  }));
356
363
  await this.deliverOutcome(triggerKey);
357
364
  }
358
365
  catch (error) {
359
366
  const submitted = submission.takeFeedback();
367
+ const submittedObservability = submission.takeObservabilityFeedback();
360
368
  submission.cancel();
361
369
  const code = error instanceof PiRuntimeError
362
370
  ? error.code
363
371
  : isMissingReplyOutcomeError(error)
364
372
  ? "outcome_missing"
365
373
  : "runtime_exit_failed";
366
- await this.fail(triggerKey, runId, code, error, submitted, settle);
374
+ await this.fail(triggerKey, runId, code, error, submitted, submittedObservability, settle);
367
375
  }
368
376
  }
369
377
  async process(triggerKey, normalize) {
@@ -1,4 +1,4 @@
1
- import type { CardContent, FeedbackContent, FinalOutcomeContent } from "../domain/types.js";
1
+ import type { CardContent, FeedbackContent, FinalOutcomeContent, ObservabilityFeedbackContent } from "../domain/types.js";
2
2
  type ToolResult = {
3
3
  content: Array<{
4
4
  type: "text";
@@ -25,6 +25,9 @@ export type CardOutcomeToolParams = {
25
25
  export type FeedbackToolParams = {
26
26
  items: FeedbackContent["items"];
27
27
  };
28
+ export type ObservabilityFeedbackToolParams = {
29
+ items: ObservabilityFeedbackContent["items"];
30
+ };
28
31
  type ExtensionApi = {
29
32
  registerTool<TParams>(tool: {
30
33
  name: string;
@@ -39,5 +42,6 @@ export declare function replyCardFromToolParams(params: CardOutcomeToolParams):
39
42
  export declare function noReplyFromToolParams(params: NoReplyOutcomeToolParams): FinalOutcomeContent;
40
43
  export declare function notifyCardFromToolParams(params: CardOutcomeToolParams): CardContent;
41
44
  export declare function feedbackFromToolParams(params: FeedbackToolParams): FeedbackContent;
45
+ export declare function observabilityFeedbackFromToolParams(params: ObservabilityFeedbackToolParams): ObservabilityFeedbackContent;
42
46
  export default function registerOutcomeTools(pi: ExtensionApi): void;
43
47
  export {};
@@ -39,6 +39,15 @@ export function feedbackFromToolParams(params) {
39
39
  throw new Error("submit_feedback produced no items");
40
40
  return patch.feedback;
41
41
  }
42
+ export function observabilityFeedbackFromToolParams(params) {
43
+ const patch = parseOutcomePatch({
44
+ observabilityFeedback: { items: params.items },
45
+ });
46
+ if (!patch.observabilityFeedback) {
47
+ throw new Error("submit_observability_feedback produced no items");
48
+ }
49
+ return patch.observabilityFeedback;
50
+ }
42
51
  async function invokeBeaconCli(outcome, signal) {
43
52
  const cliPath = process.env.BEACON_CLI_PATH;
44
53
  if (!cliPath)
@@ -209,7 +218,7 @@ export default function registerOutcomeTools(pi) {
209
218
  pi.registerTool({
210
219
  name: "submit_feedback",
211
220
  label: "Submit Feedback",
212
- description: "Optionally report one to three high or medium problems with instructions, Skills, dependencies, or tools on this Run. Call at most once, and only when such a problem actually existed. Do not call this tool when there is nothing to report.",
221
+ description: "Optionally report one to three high or medium problems with instructions, Skills, dependencies, or tools on this Run. Call at most once, and only when such a problem actually existed. Do not use this for missing observability — use submit_observability_feedback instead. Do not call this tool when there is nothing to report.",
213
222
  parameters: {
214
223
  type: "object",
215
224
  properties: {
@@ -249,4 +258,52 @@ export default function registerOutcomeTools(pi) {
249
258
  };
250
259
  },
251
260
  });
261
+ pi.registerTool({
262
+ name: "submit_observability_feedback",
263
+ label: "Submit Observability Feedback",
264
+ description: "Optionally report one to three observability gaps (missing logs, metrics, traces, or correlation signals) that held back root-cause analysis on this Run. Priority may be high, medium, or low. Call at most once, and only when such a gap actually existed. Do not use this for instruction/Skill/dependency/tool problems — use submit_feedback instead. Do not call this tool when there is nothing to report.",
265
+ parameters: {
266
+ type: "object",
267
+ properties: {
268
+ items: {
269
+ type: "array",
270
+ minItems: 1,
271
+ maxItems: 3,
272
+ description: "One to three observability findings. Omit the tool call entirely when there are none.",
273
+ items: {
274
+ type: "object",
275
+ properties: {
276
+ priority: {
277
+ type: "string",
278
+ enum: ["high", "medium", "low"],
279
+ description: "high, medium, or low — how much the missing signal limited RCA confidence.",
280
+ },
281
+ summary: {
282
+ type: "string",
283
+ minLength: 1,
284
+ maxLength: 1024,
285
+ description: "One or two sentences naming the missing signal and how adding it would help RCA.",
286
+ },
287
+ },
288
+ required: ["priority", "summary"],
289
+ additionalProperties: false,
290
+ },
291
+ },
292
+ },
293
+ required: ["items"],
294
+ additionalProperties: false,
295
+ },
296
+ async execute(_toolCallId, params, signal) {
297
+ await invokeBeaconCli({ observabilityFeedback: { items: params.items } }, signal);
298
+ return {
299
+ content: [
300
+ {
301
+ type: "text",
302
+ text: "Observability feedback accepted by Beacon.",
303
+ },
304
+ ],
305
+ details: { submitted: true },
306
+ };
307
+ },
308
+ });
252
309
  }
@@ -1,5 +1,5 @@
1
1
  import { createHash } from "node:crypto";
2
- import { feedbackContractInstructions, finalOutcomeContractInstructions, } from "../outcome/instructions.js";
2
+ import { feedbackContractInstructions, finalOutcomeContractInstructions, observabilityFeedbackContractInstructions, } from "../outcome/instructions.js";
3
3
  export function agentSystemPromptTrigger(input, notifyTarget) {
4
4
  const notify = notifyTarget !== undefined;
5
5
  if (input?.kind === "event") {
@@ -30,6 +30,8 @@ export function buildAgentSystemPrompt(profile, trigger) {
30
30
  "",
31
31
  ...feedbackContractInstructions,
32
32
  "",
33
+ ...observabilityFeedbackContractInstructions,
34
+ "",
33
35
  profile.persona,
34
36
  "",
35
37
  profile.task,
@@ -4,7 +4,7 @@ import { basename, dirname, isAbsolute, join } from "node:path";
4
4
  import { z } from "zod";
5
5
  import { failureCodes, } from "../domain/types.js";
6
6
  import { cloudEventSchema } from "../events/cloudevent.js";
7
- import { feedbackRecordSchema, finalOutcomeContentSchema, parseFinalOutcomeContent, } from "../outcome/content.js";
7
+ import { feedbackRecordSchema, finalOutcomeContentSchema, observabilityFeedbackRecordSchema, parseFinalOutcomeContent, } from "../outcome/content.js";
8
8
  const timestamp = z.string().datetime({ offset: true });
9
9
  const failureSchema = z
10
10
  .object({ code: z.enum(failureCodes), summary: z.string().min(1).max(4096) })
@@ -122,6 +122,7 @@ const triggerRecordSchema = z
122
122
  run: runSchema.optional(),
123
123
  finalOutcome: outcomeSchema.optional(),
124
124
  feedback: feedbackRecordSchema.optional(),
125
+ observabilityFeedback: observabilityFeedbackRecordSchema.optional(),
125
126
  delivery: deliverySchema.optional(),
126
127
  notifyDelivery: deliverySchema.optional(),
127
128
  })