@yaklabs-ai/plugin-sdk 0.15.3 → 0.26.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/dist/kay-app.js CHANGED
@@ -163,6 +163,94 @@ function invalidObservation(input) {
163
163
  };
164
164
  }
165
165
 
166
+ // packages/herd-transcript/dist/record-kinds.js
167
+ var STORED_TRANSCRIPT_MESSAGE_KINDS = [
168
+ "user",
169
+ "assistant",
170
+ "tool_result",
171
+ "custom_message:*",
172
+ "compaction",
173
+ "branch_summary"
174
+ ];
175
+ var NAMED_KINDS = /* @__PURE__ */ new Set([
176
+ "user",
177
+ "assistant",
178
+ "tool_result",
179
+ "compaction",
180
+ "branch_summary",
181
+ "other",
182
+ "unreadable"
183
+ ]);
184
+ var ROLE_KINDS = {
185
+ user: "user",
186
+ assistant: "assistant",
187
+ toolResult: "tool_result"
188
+ };
189
+ function storedTranscriptKindOf(record) {
190
+ if (!("entry" in record))
191
+ return "unreadable";
192
+ const entry = record.entry;
193
+ switch (entry.type) {
194
+ case "message": {
195
+ const message = entry.message;
196
+ if (message.role === "custom") {
197
+ return `custom_message:${typeof message.customType === "string" ? message.customType : ""}`;
198
+ }
199
+ return (typeof message.role === "string" ? ROLE_KINDS[message.role] : void 0) ?? "other";
200
+ }
201
+ case "custom":
202
+ return `custom:${entry.customType}`;
203
+ case "compaction":
204
+ return "compaction";
205
+ case "branch_summary":
206
+ return "branch_summary";
207
+ default:
208
+ return "other";
209
+ }
210
+ }
211
+ function parseStoredTranscriptKindFilter(tokens) {
212
+ const exact = /* @__PURE__ */ new Set();
213
+ const families = /* @__PURE__ */ new Set();
214
+ let all = false;
215
+ for (const raw of tokens) {
216
+ const token = raw.trim();
217
+ if (token === "all") {
218
+ all = true;
219
+ } else if (token === "messages") {
220
+ for (const kind of STORED_TRANSCRIPT_MESSAGE_KINDS)
221
+ addToken(kind);
222
+ } else if (!addToken(token)) {
223
+ return { ok: false, invalid: raw };
224
+ }
225
+ }
226
+ return {
227
+ ok: true,
228
+ filter: {
229
+ includes: (kind) => all || exact.has(kind) || families.has(kind.slice(0, kind.indexOf(":") + 1))
230
+ }
231
+ };
232
+ function addToken(token) {
233
+ if (NAMED_KINDS.has(token)) {
234
+ exact.add(token);
235
+ return true;
236
+ }
237
+ const family = /^(custom|custom_message):(.+)$/.exec(token);
238
+ if (family === null)
239
+ return false;
240
+ if (family[2] === "*")
241
+ families.add(`${family[1]}:`);
242
+ else
243
+ exact.add(token);
244
+ return true;
245
+ }
246
+ }
247
+ var STORED_TRANSCRIPT_MESSAGE_FILTER = (() => {
248
+ const parsed = parseStoredTranscriptKindFilter(STORED_TRANSCRIPT_MESSAGE_KINDS);
249
+ if (!parsed.ok)
250
+ throw new Error(`invalid default kinds: ${parsed.invalid}`);
251
+ return parsed.filter;
252
+ })();
253
+
166
254
  // packages/plugin-sdk/dist/kay-app/index.js
167
255
  import { pathToFileURL } from "node:url";
168
256
 
@@ -190,6 +278,15 @@ var UriValidationError = class extends UriError {
190
278
  this.name = "UriValidationError";
191
279
  }
192
280
  };
281
+ function requireWriteContent(payload2, uri) {
282
+ if (payload2 === void 0) {
283
+ throw new UriValidationError(`Writing ${uri} needs \`content\` (or a \`source\` to copy from): pass the payload this address takes, which its help names.`);
284
+ }
285
+ if (payload2 instanceof Uint8Array) {
286
+ throw new UriValidationError(`${uri} stores text only, so it cannot take raw bytes. Copy the file to an address that accepts bytes.`);
287
+ }
288
+ return payload2;
289
+ }
193
290
  var UriProviderError = class extends UriError {
194
291
  _tag = "UriProviderError";
195
292
  moduleId;
@@ -400,7 +497,7 @@ function toJsonSchema(schema) {
400
497
  // `io: "input"` describes what a caller may SEND, which is what a parameter and an
401
498
  // `accepts` payload advertise: a field with a Zod default is optional on the wire even
402
499
  // though the parsed value always carries it. Strictness still survives where the validator
403
- // really enforces it — `z.strictObject` emits `additionalProperties: false`, while a plain
500
+ // really enforces it - `z.strictObject` emits `additionalProperties: false`, while a plain
404
501
  // `z.object` correctly does not, because it TOLERATES unknown keys and silently strips
405
502
  // them. A `returns` payload derived from a Zod schema is described in the same input terms;
406
503
  // no module does that today, and a faithful output projection would need its own seam.
@@ -440,6 +537,211 @@ function isRetryable(result) {
440
537
  return result.status === "not-ready";
441
538
  }
442
539
 
540
+ // packages/kay-ui-catalog/dist/message-draft-resource.js
541
+ import { z as z7 } from "zod";
542
+ var MESSAGE_DRAFT_SUBJECT_MAX = 300;
543
+ var MESSAGE_DRAFT_BODY_MAX = 2e4;
544
+ var MESSAGE_DRAFT_RESOURCE_MAX = 8;
545
+ var UI_RENDER_RESULT_MAX_BYTES = 64 * 1024;
546
+ var contextIdSchema = z7.string().min(1).max(2048);
547
+ var gmailDeliveryRequestSchema = z7.strictObject({
548
+ provider: z7.literal("gmail"),
549
+ accountId: contextIdSchema,
550
+ threadId: contextIdSchema.optional(),
551
+ inReplyTo: contextIdSchema.optional(),
552
+ references: z7.array(contextIdSchema).max(50).optional()
553
+ });
554
+ var messageDraftDeliveryRequestSchema = z7.discriminatedUnion("provider", [
555
+ gmailDeliveryRequestSchema,
556
+ z7.strictObject({
557
+ provider: z7.literal("slack"),
558
+ accountId: contextIdSchema,
559
+ threadTs: contextIdSchema.optional()
560
+ }),
561
+ z7.strictObject({
562
+ provider: z7.literal("teams"),
563
+ accountId: contextIdSchema,
564
+ replyTo: contextIdSchema.optional()
565
+ })
566
+ ]);
567
+ var slackInlineDeliveryRequestSchema = z7.strictObject({
568
+ provider: z7.literal("slack"),
569
+ accountId: contextIdSchema,
570
+ /**
571
+ * The conversation itself: `slack://channels/<id>`, or the same under `slack://@<accountId>/`.
572
+ * A thread's address is refused unless `threadTs` names the same thread, because the card shows
573
+ * a reply only from `threadTs`.
574
+ */
575
+ conversationUri: contextIdSchema,
576
+ threadTs: contextIdSchema.optional()
577
+ });
578
+ var messageDraftInlineDeliveryRequestSchema = z7.discriminatedUnion("provider", [gmailDeliveryRequestSchema, slackInlineDeliveryRequestSchema]);
579
+ var messageDraftResourcePropsSchema = z7.strictObject({
580
+ draftUri: z7.string().min(1).max(2048),
581
+ editable: z7.boolean().optional(),
582
+ delivery: messageDraftDeliveryRequestSchema.optional()
583
+ });
584
+ var deliveryResultSchema = z7.discriminatedUnion("status", [
585
+ z7.strictObject({
586
+ status: z7.literal("ready"),
587
+ sessionId: contextIdSchema,
588
+ // A saved draft's request, or an inline card's. They differ only for Slack, where the inline
589
+ // form carries `conversationUri`; each strict variant refuses the other's shape.
590
+ request: z7.union([
591
+ messageDraftDeliveryRequestSchema,
592
+ slackInlineDeliveryRequestSchema
593
+ ]),
594
+ accountName: z7.string().min(1).max(2048).optional(),
595
+ /**
596
+ * Where a chat message lands, named as the provider named it when the card was drawn
597
+ * (`#engineering`, `Alex Kim <alex@example.com> (direct message)`: a direct message by the
598
+ * person's name and Slack email, never a display name alone; Slack's module may answer from its
599
+ * own name cache, up to a day old, never for another conversation). The card shows this instead of the
600
+ * agent's own `to` label. Absent for email, whose recipients are the card's own props.
601
+ */
602
+ destination: z7.string().min(1).max(2048).optional(),
603
+ writeUri: contextIdSchema
604
+ }),
605
+ z7.strictObject({
606
+ status: z7.literal("unavailable"),
607
+ reason: z7.enum([
608
+ "missing-context",
609
+ "account-unavailable",
610
+ "invalid-destination",
611
+ "invalid-content",
612
+ // The provider could not name the conversation in time, so the card could not show the
613
+ // person where Send would post.
614
+ "unnamed-destination"
615
+ ])
616
+ })
617
+ ]);
618
+ var contentSchema = z7.discriminatedUnion("kind", [
619
+ z7.strictObject({
620
+ kind: z7.literal("email"),
621
+ to: z7.array(z7.string().max(320)).max(50),
622
+ /** Copy recipients a draft stored in the mail provider carries; a Whiteboard draft has none. */
623
+ cc: z7.array(z7.string().max(320)).max(50).optional(),
624
+ bcc: z7.array(z7.string().max(320)).max(50).optional(),
625
+ subject: z7.string().max(MESSAGE_DRAFT_SUBJECT_MAX),
626
+ bodyMarkdown: z7.string().max(MESSAGE_DRAFT_BODY_MAX),
627
+ /**
628
+ * `plain` when `bodyMarkdown` holds the literal text of a draft stored in the mail provider,
629
+ * which is sent as written and must not be shown through a Markdown reading. Absent means
630
+ * Markdown, the Whiteboard draft's format.
631
+ */
632
+ bodyFormat: z7.literal("plain").optional(),
633
+ /** File names a draft stored in the mail provider carries (names only, never content). */
634
+ attachments: z7.array(z7.string().min(1).max(200)).max(20).optional()
635
+ }),
636
+ z7.strictObject({
637
+ kind: z7.literal("chat"),
638
+ provider: z7.enum(["slack", "teams"]),
639
+ conversationUri: z7.string().max(2048).optional(),
640
+ bodyMarkdown: z7.string().max(MESSAGE_DRAFT_BODY_MAX)
641
+ })
642
+ ]);
643
+ var messageDraftResourceSchema = z7.discriminatedUnion("status", [
644
+ z7.strictObject({
645
+ status: z7.literal("available"),
646
+ draftUri: z7.string().min(1).max(2048),
647
+ revision: z7.string().min(1).max(256),
648
+ content: contentSchema,
649
+ delivery: deliveryResultSchema.optional()
650
+ }).refine(({ content, delivery }) => delivery?.status !== "ready" || delivery.request.provider === (content.kind === "email" ? "gmail" : content.provider) && // A saved draft names its own conversation; only an inline card's request carries one.
651
+ messageDraftDeliveryRequestSchema.safeParse(delivery.request).success, "Delivery provider must match the saved content"),
652
+ z7.strictObject({
653
+ status: z7.enum([
654
+ "missing",
655
+ "unavailable",
656
+ "invalid",
657
+ "unsupported-version",
658
+ "too-large"
659
+ ]),
660
+ draftUri: z7.string().max(2048)
661
+ })
662
+ ]);
663
+ var messageDraftResourceSubmissionSchema = z7.strictObject({
664
+ version: z7.literal(1),
665
+ approved: z7.literal(true),
666
+ elementId: z7.string().min(1).max(2048),
667
+ draftUri: z7.string().min(1).max(2048),
668
+ revision: z7.string().min(1).max(256),
669
+ body: z7.string().max(MESSAGE_DRAFT_BODY_MAX),
670
+ subject: z7.string().max(MESSAGE_DRAFT_SUBJECT_MAX).optional()
671
+ });
672
+ var messageDraftApprovalWriteSchema = z7.strictObject({
673
+ messageDraftApproval: z7.strictObject({
674
+ version: z7.literal(1),
675
+ toolCallId: contextIdSchema
676
+ })
677
+ });
678
+ var messageDraftSentDetailsSchema = z7.object({
679
+ version: z7.literal(1),
680
+ /** The `ui_render` call that drew the card. */
681
+ reviewToolCallId: z7.string().min(1),
682
+ /** The MessageDraft element within that render. */
683
+ elementId: z7.string().min(1),
684
+ /** The send intent that produced this record. */
685
+ clientIntentId: z7.string().min(1),
686
+ provider: z7.enum(["gmail", "slack"]),
687
+ accountId: z7.string().min(1),
688
+ accountName: z7.string().min(1).optional(),
689
+ /** A chat message's conversation as the card named it (`#engineering`); absent for email. */
690
+ destination: z7.string().min(1).optional(),
691
+ /** ISO 8601 instant the provider accepted the send. */
692
+ sentAt: z7.string().min(1),
693
+ /**
694
+ * The sent message, addressed under its account (`gmail://@<accountId>/messages/<id>`,
695
+ * `slack://@<accountId>/channels/<id>/messages/<ts>`), when the provider named it.
696
+ */
697
+ sentMessageUri: z7.string().min(1).optional(),
698
+ subject: z7.string().max(MESSAGE_DRAFT_SUBJECT_MAX).optional(),
699
+ body: z7.string().max(MESSAGE_DRAFT_BODY_MAX)
700
+ });
701
+ var uiRenderResultDetailsSchema = z7.union([
702
+ z7.strictObject({
703
+ version: z7.literal(1),
704
+ messageDrafts: z7.record(z7.string(), messageDraftResourceSchema).refine((drafts) => Object.keys(drafts).length <= MESSAGE_DRAFT_RESOURCE_MAX).optional(),
705
+ inlineDeliveries: z7.record(z7.string(), deliveryResultSchema).refine((deliveries) => Object.keys(deliveries).length <= MESSAGE_DRAFT_RESOURCE_MAX).refine((deliveries) => Object.values(deliveries).every((delivery) => delivery.status !== "ready" || messageDraftInlineDeliveryRequestSchema.safeParse(delivery.request).success)).optional()
706
+ }).refine((details) => details.messageDrafts !== void 0 || details.inlineDeliveries !== void 0).refine((details) => new TextEncoder().encode(JSON.stringify(details)).byteLength <= UI_RENDER_RESULT_MAX_BYTES),
707
+ z7.strictObject({
708
+ version: z7.literal(1),
709
+ error: z7.literal("resource-limit-exceeded")
710
+ })
711
+ ]);
712
+
713
+ // packages/plugin-sdk/dist/kay-app/approvals.js
714
+ var MessageApprovalPreparationError = class extends Error {
715
+ reason;
716
+ constructor(reason) {
717
+ super(reason);
718
+ this.reason = reason;
719
+ this.name = "MessageApprovalPreparationError";
720
+ }
721
+ };
722
+
723
+ // packages/plugin-sdk/dist/kay-app/auth.js
724
+ var KayAppCredentialRejectedError = class extends Error {
725
+ name = "KayAppCredentialRejectedError";
726
+ };
727
+ async function withCredential(auth, request, use) {
728
+ const candidates = await auth.resolveCandidates(request);
729
+ let rejection;
730
+ for (const credential of candidates) {
731
+ try {
732
+ const result = await use(credential);
733
+ await auth.reportWorked(request, credential.schemeId).catch(() => {
734
+ });
735
+ return result;
736
+ } catch (error) {
737
+ if (!(error instanceof KayAppCredentialRejectedError))
738
+ throw error;
739
+ rejection = error;
740
+ }
741
+ }
742
+ throw rejection ?? new Error(`No credential is resolvable for '${request.serviceId}'.`);
743
+ }
744
+
443
745
  // packages/plugin-sdk/dist/kay-app/automations.js
444
746
  var KAY_APP_AUTOMATION_CONDITION_KINDS = [
445
747
  "time",
@@ -449,6 +751,46 @@ var KAY_APP_AUTOMATION_CONDITION_KINDS = [
449
751
  "delayed-occurrence"
450
752
  ];
451
753
 
754
+ // packages/plugin-sdk/dist/log.js
755
+ function createKayPluginLog(write, bound = {}) {
756
+ const at = (level) => (name, message, details) => {
757
+ try {
758
+ write({
759
+ level,
760
+ name,
761
+ message,
762
+ ...details?.error === void 0 ? {} : { error: details.error },
763
+ ...details?.sessionId === void 0 ? {} : { sessionId: details.sessionId },
764
+ attributes: { ...bound, ...details?.attributes }
765
+ });
766
+ } catch {
767
+ }
768
+ };
769
+ return {
770
+ debug: at("debug"),
771
+ info: at("info"),
772
+ warn: at("warn"),
773
+ error: at("error"),
774
+ child: (attributes) => createKayPluginLog(write, { ...bound, ...attributes })
775
+ };
776
+ }
777
+ function createConsoleKayPluginLog(pluginId) {
778
+ const prefix = pluginId === void 0 ? "" : `${pluginId}.`;
779
+ return createKayPluginLog((line) => {
780
+ const args = [`[${prefix}${line.name}] ${line.message}`];
781
+ if (Object.keys(line.attributes).length > 0)
782
+ args.push(line.attributes);
783
+ if (line.error !== void 0)
784
+ args.push(line.error);
785
+ console[line.level](...args);
786
+ });
787
+ }
788
+
789
+ // packages/plugin-sdk/dist/kay-app/model-selection.js
790
+ var KAY_APP_MODEL_SELECTION_START_BOUND_MS = 2e3;
791
+ var KAY_APP_MODEL_SELECTION_RESPONSE_BOUND_MS = 6e3;
792
+ var KAY_APP_MODEL_SELECTION_SEND_BOUND_MS = 4e3;
793
+
452
794
  // packages/plugin-sdk/dist/kay-app/poller.js
453
795
  function accountCursors(state) {
454
796
  if (state === void 0)
@@ -482,7 +824,7 @@ function plainText(value, max) {
482
824
  return text;
483
825
  }
484
826
  function definePoller(app, localId, options) {
485
- const { workflows, auth, events } = app;
827
+ const { workflows, auth, backgroundAuth, events } = app;
486
828
  if (!workflows)
487
829
  throw new Error("Poller requires workflows");
488
830
  if (!Number.isSafeInteger(options.every) || options.every <= 0) {
@@ -498,6 +840,8 @@ function definePoller(app, localId, options) {
498
840
  async run(ctx) {
499
841
  if (!auth)
500
842
  throw new Error("Poller requires account listing");
843
+ if (!backgroundAuth)
844
+ throw new Error("Poller requires background auth");
501
845
  const previous = accountCursors(ctx.state);
502
846
  const accounts = await ctx.runStep(async () => {
503
847
  const listed = await auth.listAccounts({
@@ -523,7 +867,12 @@ function definePoller(app, localId, options) {
523
867
  }
524
868
  let credential;
525
869
  try {
526
- credential = await options.resolveCredential(account, ctx.runId);
870
+ credential = await backgroundAuth.resolveCredential({
871
+ serviceId: options.serviceId,
872
+ schemeId: account.schemeId,
873
+ accountId: account.accountId,
874
+ jobId: ctx.runId
875
+ });
527
876
  } catch {
528
877
  throw new Error("Poller credential resolution failed");
529
878
  }
@@ -597,6 +946,15 @@ function definePoller(app, localId, options) {
597
946
  });
598
947
  }
599
948
 
949
+ // packages/plugin-sdk/dist/kay-app/sealing.js
950
+ var KAY_APP_SEALING_MAX_BYTES = 1048576;
951
+ function createUnavailableSealing(message) {
952
+ return {
953
+ seal: async () => ({ status: "unavailable", message }),
954
+ open: async () => ({ status: "unavailable", message })
955
+ };
956
+ }
957
+
600
958
  // packages/plugin-sdk/dist/kay-app/skills.js
601
959
  function createUnavailableSkills(message) {
602
960
  const unavailable = {
@@ -605,9 +963,38 @@ function createUnavailableSkills(message) {
605
963
  message
606
964
  };
607
965
  return {
966
+ propose: async () => {
967
+ throw new Error(message);
968
+ },
608
969
  list: async () => unavailable,
609
970
  read: async () => unavailable,
610
- history: async () => unavailable
971
+ history: async () => unavailable,
972
+ diff: async () => unavailable,
973
+ revision: async () => unavailable,
974
+ writeFile: async () => {
975
+ throw new Error(message);
976
+ },
977
+ install: async () => {
978
+ throw new Error(message);
979
+ },
980
+ delete: async () => {
981
+ throw new Error(message);
982
+ },
983
+ sourceContributors: async () => {
984
+ throw new Error(message);
985
+ },
986
+ setMarketplaceAdded: async () => {
987
+ throw new Error(message);
988
+ },
989
+ shareDestinations: async () => {
990
+ throw new Error(message);
991
+ },
992
+ prepareShare: async () => {
993
+ throw new Error(message);
994
+ },
995
+ confirmShare: async () => {
996
+ throw new Error(message);
997
+ }
611
998
  };
612
999
  }
613
1000
 
@@ -649,7 +1036,8 @@ function transcriptRoleLabel(role) {
649
1036
  // packages/plugin-sdk/dist/kay-app/usage.js
650
1037
  function createUnavailableUsage(message) {
651
1038
  return {
652
- uriActivity: async () => ({ status: "unavailable", message })
1039
+ uriActivity: async () => ({ status: "unavailable", message }),
1040
+ skillInvocations: async () => ({ status: "unavailable", message })
653
1041
  };
654
1042
  }
655
1043
 
@@ -677,15 +1065,28 @@ export {
677
1065
  KAY_APP_AUTOMATION_CONDITION_KINDS,
678
1066
  KAY_APP_DATA_CHANGE_MAX_BYTES,
679
1067
  KAY_APP_DATA_SNAPSHOT_MAX_BYTES,
1068
+ KAY_APP_MODEL_SELECTION_RESPONSE_BOUND_MS,
1069
+ KAY_APP_MODEL_SELECTION_SEND_BOUND_MS,
1070
+ KAY_APP_MODEL_SELECTION_START_BOUND_MS,
1071
+ KAY_APP_SEALING_MAX_BYTES,
1072
+ KayAppCredentialRejectedError,
680
1073
  KayAppWorkflowFailure,
681
1074
  MAX_CHOICE_LABELS,
1075
+ MESSAGE_DRAFT_BODY_MAX,
1076
+ MESSAGE_DRAFT_SUBJECT_MAX,
1077
+ MessageApprovalPreparationError,
682
1078
  SIGNAL_TIME_MAX_MS,
1079
+ STORED_TRANSCRIPT_MESSAGE_FILTER,
1080
+ STORED_TRANSCRIPT_MESSAGE_KINDS,
683
1081
  UriConflictError,
684
1082
  UriNotFoundError,
685
1083
  UriProviderError,
686
1084
  UriUnsupportedOperationError,
687
1085
  UriValidationError,
1086
+ createConsoleKayPluginLog,
688
1087
  createFallbackOnlySignals,
1088
+ createKayPluginLog,
1089
+ createUnavailableSealing,
689
1090
  createUnavailableSkills,
690
1091
  createUnavailableTools,
691
1092
  createUnavailableUsage,
@@ -693,10 +1094,15 @@ export {
693
1094
  failedRunCause,
694
1095
  invalidObservation,
695
1096
  isRetryable,
1097
+ messageDraftResourceSchema,
696
1098
  parseLineSelector,
1099
+ parseStoredTranscriptKindFilter,
697
1100
  pathToFileURL,
698
1101
  payload,
1102
+ requireWriteContent,
1103
+ storedTranscriptKindOf,
699
1104
  transcriptMessageText,
700
1105
  transcriptMessageTexts,
701
- transcriptRoleLabel
1106
+ transcriptRoleLabel,
1107
+ withCredential
702
1108
  };
@@ -28,7 +28,7 @@ declare type PhaseShiftCost = z.infer<typeof phaseShiftCostSchema>;
28
28
  * the feature accounts for itself.
29
29
  *
30
30
  * Absent on a record written before the detector accounted for itself, and on
31
- * a call no attempt priced — absence means "not recorded", never zero.
31
+ * a call no attempt priced - absence means "not recorded", never zero.
32
32
  */
33
33
  declare const phaseShiftCostSchema: z.ZodObject<{
34
34
  amountUsd: z.ZodNumber;
@@ -45,7 +45,7 @@ declare const phaseShiftCostSchema: z.ZodObject<{
45
45
  /** One accepted transition, placed in time. */
46
46
  export declare interface PhaseShiftTimelineChange {
47
47
  readonly startEntryId: string;
48
- /** When the new work began — the onset entry's own timestamp, not the judgment's. */
48
+ /** When the new work began - the onset entry's own timestamp, not the judgment's. */
49
49
  readonly startedAt: string;
50
50
  readonly relation: "outcome" | "phase";
51
51
  readonly reason: string;
@@ -69,7 +69,7 @@ export declare function phaseShiftTimelineFromEntries(entries: readonly Transcri
69
69
  *
70
70
  * A record is evidence about the span it names and nothing else: time outside
71
71
  * every record's `[windowStartAt, throughAt]` is unobserved, which is not the
72
- * same as unchanged. An empty `changes` is the opposite — a check that ran and
72
+ * same as unchanged. An empty `changes` is the opposite - a check that ran and
73
73
  * found no transition.
74
74
  */
75
75
  export declare interface PhaseShiftTimelineRecord {
@@ -100,7 +100,7 @@ declare interface TranscriptEntryLike {
100
100
  readonly id: string;
101
101
  readonly type: string;
102
102
  readonly customType?: string;
103
- /** Opaque. Never parsed or validated here — a feature's own schema owns that. */
103
+ /** Opaque. Never parsed or validated here - a feature's own schema owns that. */
104
104
  readonly data?: unknown;
105
105
  }
106
106
 
@@ -231,12 +231,25 @@ export declare interface SystemOneAvailability {
231
231
  readonly cause?: SystemOneFailureCause;
232
232
  }
233
233
 
234
+ /** Structurally the plugin SDK's `KayAppSessionEventCause`: only the fields the host reads. */
235
+ declare interface SystemOneCallCause {
236
+ readonly kind?: "session-event" | "backfill";
237
+ readonly handler: string;
238
+ readonly sourceSessionId: string;
239
+ }
240
+
234
241
  export declare interface SystemOneCallOptions {
235
242
  readonly signal?: AbortSignal;
236
243
  /** Bounds the whole call, retries included. */
237
244
  readonly timeoutMs?: number;
238
245
  /** What the call is for, carried to the host's usage accounting. Never sent to a provider. */
239
246
  readonly purpose?: string;
247
+ /**
248
+ * The session event a plugin's call answers, so the host charges the call to that session.
249
+ * The host checks the plugin is handling that session's event right now. Never sent to a
250
+ * provider.
251
+ */
252
+ readonly cause?: SystemOneCallCause;
240
253
  }
241
254
 
242
255
  export declare interface SystemOneClient {
package/dist/time.d.ts CHANGED
@@ -17,7 +17,7 @@ export declare function isValidZone(id: unknown): boolean;
17
17
  /**
18
18
  * `app.time` / `api.time`: host facts about time. Added to `kay.app` in SDK 0.12.1 and to
19
19
  * `kay.agent` with the calendar zone-of-record work: a plugin that calls it declares
20
- * `compatibility.sdk` `^0.12.1`, so an older Bonsai refuses a directory or repository plugin at
20
+ * `compatibility.sdk` `^0.19.0`, so an older Bonsai refuses a directory or repository plugin at
21
21
  * load instead of the call failing.
22
22
  */
23
23
  export declare interface KayAppTime {
@@ -27,9 +27,7 @@ export declare interface KayAppTime {
27
27
  * Every call asks the host again and returns a new object; nothing is cached. Call it where you
28
28
  * need the value (inside a tool, a handler or a workflow step), not inside `activate()`: a value
29
29
  * read there is as old as the activation, and the host can run a bundled plugin's `activate()`
30
- * against a recording api that has no `time`, so a read there throws. The exception is a
31
- * directory plugin that declares a workflow with a cron `timezone`: `workflows.define` is legal
32
- * only during `activate()`, so it reads the zone there, and the schedule then keeps that zone.
30
+ * against a recording api that has no `time`, so a read there throws.
33
31
  * Keep the result for as long as you use it, and not across a long wait (a sleep, a timer, a
34
32
  * queued run): the zone can change while you wait. On a daemon that runs on the user's machine,
35
33
  * a change of the process's `TZ` shows in the next call. A `TZ` that names a zone wins over the
@@ -152,6 +152,16 @@ export declare interface TranscriptReview {
152
152
  readonly start: number;
153
153
  readonly end: number;
154
154
  } | undefined;
155
+ /**
156
+ * The run whose own extent holds this position, the one starting latest; among runs that
157
+ * start at the same position, the first in run order. Undefined before the first run and at
158
+ * or after the end.
159
+ */
160
+ runAt(position: number): {
161
+ readonly runId: string;
162
+ readonly start: number;
163
+ readonly end: number;
164
+ } | undefined;
155
165
  /** The run input carrying this input id. */
156
166
  inputById(inputId: string): TranscriptReviewRunInput | undefined;
157
167
  attemptAt(position: number, block: number): ToolCallAttempt | undefined;