@yaklabs-ai/plugin-sdk 0.26.3 → 0.27.1

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
@@ -13,7 +13,7 @@ it under the name your plugin code actually imports:
13
13
  ```json
14
14
  {
15
15
  "dependencies": {
16
- "@bonsai/plugin-sdk": "npm:@yaklabs-ai/plugin-sdk@^0.26.3"
16
+ "@bonsai/plugin-sdk": "npm:@yaklabs-ai/plugin-sdk@^0.27.1"
17
17
  }
18
18
  }
19
19
  ```
@@ -62,7 +62,7 @@ Every tool the entrypoint registers is declared in the manifest too:
62
62
  "description": "Greets people by name.",
63
63
  "version": "0.1.0",
64
64
  "namespace": "widgets",
65
- "compatibility": { "sdk": "^0.26.3" },
65
+ "compatibility": { "sdk": "^0.27.1" },
66
66
  "targets": {
67
67
  "kay": {
68
68
  "agent": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "package": "@yaklabs-ai/plugin-sdk",
4
- "version": "0.26.3",
4
+ "version": "0.27.1",
5
5
  "target": "npm",
6
6
  "firstPartyLicense": "MIT",
7
7
  "bundled": [
@@ -1113,7 +1113,7 @@ function mergeMessageContent(item, event, status) {
1113
1113
  // The terminal merge (message_end) stamps completion; `startedAt` was
1114
1114
  // stamped at message_start and is never overwritten by later events.
1115
1115
  ...status === "streaming" || item.completedAt !== void 0 ? {} : stringField("completedAt", getTimestamp(event)),
1116
- ...messageMetadata(event, textPhaseFor(event, effectiveParts), effectiveParts)
1116
+ ...messageMetadata(event, textPhaseFor(event, effectiveParts, item.parts), effectiveParts)
1117
1117
  };
1118
1118
  }
1119
1119
  function mergeMessageDelta(item, event) {
@@ -1263,12 +1263,12 @@ function messageFailureReason(event) {
1263
1263
  ...errorText === void 0 ? {} : { failureText: readableFailureText(errorText) }
1264
1264
  };
1265
1265
  }
1266
- function textPhaseFor(event, parts) {
1266
+ function textPhaseFor(event, parts, streamedParts = []) {
1267
1267
  if (event.type !== "message_end")
1268
1268
  return "provisional";
1269
+ const isCall = (part) => part.type === "tool_call";
1270
+ const callsTool = parts.some(isCall) || streamedParts.some(isCall);
1269
1271
  switch (finishReasonFor(event, parts)) {
1270
- case "tool_use":
1271
- return "narration";
1272
1272
  case "complete":
1273
1273
  return "final";
1274
1274
  case "interrupted":
@@ -1276,8 +1276,11 @@ function textPhaseFor(event, parts) {
1276
1276
  return "interrupted";
1277
1277
  case "error":
1278
1278
  return "error";
1279
+ // Text is narration only beside a call it leads into. A provider can report `tool_use`
1280
+ // with no call in the message; that text is the reply, as a stop's would be.
1281
+ case "tool_use":
1279
1282
  case "unknown":
1280
- return parts.some((part) => part.type === "tool_call") ? "narration" : "final";
1283
+ return callsTool ? "narration" : "final";
1281
1284
  case void 0:
1282
1285
  return "final";
1283
1286
  }
@@ -2306,8 +2306,20 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2306
2306
  * registers the named function on any such scheme, its own client's included, and the SDK refuses a
2307
2307
  * plugin whose lookup and manifest disagree. An own-client (`pkce`) scheme may carry the
2308
2308
  * `clientSecret` that goes with its `clientId`. A plugin with an `oauth2` sign-in declares ^0.26.3.
2309
+ *
2310
+ * 0.27.0 makes a message approval card manifest data (#14574). `approvalTypes` declares the card's
2311
+ * facts and forms, and Bonsai draws it with the module's `describeOperation` and sends it with its
2312
+ * `write`. `app.approvals`, its `prepare`, `finalize` and `resolveResource` are gone, and a write can
2313
+ * refuse in the person's words with `UriProviderError.refusalMessage`. No plugin outside this repo
2314
+ * declared a card, so 0.26.3 stays served. A plugin that declares a card declares ^0.27.0.
2315
+ *
2316
+ * 0.27.1 lets a manifest URI module name the exact sign-in scheme its calls use, as a tool can
2317
+ * (#14928): `authScheme`, a scheme of the module's `authService`, local or another plugin's. A
2318
+ * hosted module's code and manifest must agree on it, and the daemon reads it to find an
2319
+ * external-CLI scheme without running the module. A module that runs in the daemon is unchanged,
2320
+ * so this is additive; a plugin whose manifest sets `authScheme` declares ^0.27.1.
2309
2321
  */
2310
- declare const KAY_PLUGIN_SDK_VERSION: "0.26.3";
2322
+ declare const KAY_PLUGIN_SDK_VERSION: "0.27.1";
2311
2323
 
2312
2324
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2313
2325
 
@@ -2360,8 +2360,20 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2360
2360
  * registers the named function on any such scheme, its own client's included, and the SDK refuses a
2361
2361
  * plugin whose lookup and manifest disagree. An own-client (`pkce`) scheme may carry the
2362
2362
  * `clientSecret` that goes with its `clientId`. A plugin with an `oauth2` sign-in declares ^0.26.3.
2363
+ *
2364
+ * 0.27.0 makes a message approval card manifest data (#14574). `approvalTypes` declares the card's
2365
+ * facts and forms, and Bonsai draws it with the module's `describeOperation` and sends it with its
2366
+ * `write`. `app.approvals`, its `prepare`, `finalize` and `resolveResource` are gone, and a write can
2367
+ * refuse in the person's words with `UriProviderError.refusalMessage`. No plugin outside this repo
2368
+ * declared a card, so 0.26.3 stays served. A plugin that declares a card declares ^0.27.0.
2369
+ *
2370
+ * 0.27.1 lets a manifest URI module name the exact sign-in scheme its calls use, as a tool can
2371
+ * (#14928): `authScheme`, a scheme of the module's `authService`, local or another plugin's. A
2372
+ * hosted module's code and manifest must agree on it, and the daemon reads it to find an
2373
+ * external-CLI scheme without running the module. A module that runs in the daemon is unchanged,
2374
+ * so this is additive; a plugin whose manifest sets `authScheme` declares ^0.27.1.
2363
2375
  */
2364
- declare const KAY_PLUGIN_SDK_VERSION: "0.26.3";
2376
+ declare const KAY_PLUGIN_SDK_VERSION: "0.27.1";
2365
2377
 
2366
2378
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2367
2379
 
@@ -4703,9 +4715,9 @@ declare const ResolvedPluginContractV1: z.ZodObject<{
4703
4715
  endpoint: "endpoint";
4704
4716
  storage: "storage";
4705
4717
  command: "command";
4718
+ uriModule: "uriModule";
4706
4719
  authService: "authService";
4707
4720
  app: "app";
4708
- uriModule: "uriModule";
4709
4721
  configSection: "configSection";
4710
4722
  skill: "skill";
4711
4723
  converter: "converter";
@@ -5360,6 +5372,7 @@ declare const ResolvedPluginContractV1: z.ZodObject<{
5360
5372
  schemes: z.ZodArray<z.ZodString>;
5361
5373
  displayName: z.ZodOptional<z.ZodString>;
5362
5374
  authServiceId: z.ZodOptional<z.ZodString>;
5375
+ authSchemeId: z.ZodOptional<z.ZodString>;
5363
5376
  knownResources: z.ZodOptional<z.ZodLiteral<true>>;
5364
5377
  describesOperations: z.ZodOptional<z.ZodLiteral<true>>;
5365
5378
  }, z.core.$strict>>>;
@@ -5419,14 +5432,80 @@ declare const ResolvedPluginContractV1: z.ZodObject<{
5419
5432
  toolName: z.ZodString;
5420
5433
  }, z.core.$strict>>>;
5421
5434
  kayAppApprovalTypes: z.ZodOptional<z.ZodArray<z.ZodObject<{
5435
+ kind: z.ZodLiteral<"message">;
5422
5436
  localId: z.ZodString;
5437
+ provider: z.ZodString;
5438
+ unknownMessage: z.ZodString;
5439
+ fields: z.ZodObject<{
5440
+ body: z.ZodObject<{
5441
+ key: z.ZodString;
5442
+ max: z.ZodNumber;
5443
+ }, z.core.$strict>;
5444
+ subject: z.ZodOptional<z.ZodObject<{
5445
+ key: z.ZodString;
5446
+ max: z.ZodNumber;
5447
+ }, z.core.$strict>>;
5448
+ }, z.core.$strict>;
5449
+ presentation: z.ZodObject<{
5450
+ showAccount: z.ZodBoolean;
5451
+ recipient: z.ZodEnum<{
5452
+ target: "target";
5453
+ person: "person";
5454
+ }>;
5455
+ }, z.core.$strict>;
5456
+ forms: z.ZodObject<{
5457
+ inline: z.ZodOptional<z.ZodObject<{
5458
+ uri: z.ZodUnion<readonly [z.ZodObject<{
5459
+ fixed: z.ZodString;
5460
+ }, z.core.$strict>, z.ZodObject<{
5461
+ value: z.ZodString;
5462
+ }, z.core.$strict>]>;
5463
+ requestFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
5464
+ payload: z.ZodRecord<z.ZodString, z.ZodString>;
5465
+ fixed: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>>;
5466
+ }, z.core.$strict>>;
5467
+ saved: z.ZodOptional<z.ZodObject<{
5468
+ uri: z.ZodUnion<readonly [z.ZodObject<{
5469
+ fixed: z.ZodString;
5470
+ }, z.core.$strict>, z.ZodObject<{
5471
+ value: z.ZodString;
5472
+ }, z.core.$strict>]>;
5473
+ requestFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
5474
+ payload: z.ZodRecord<z.ZodString, z.ZodString>;
5475
+ fixed: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>>;
5476
+ }, z.core.$strict>>;
5477
+ stored: z.ZodOptional<z.ZodObject<{
5478
+ uri: z.ZodUnion<readonly [z.ZodObject<{
5479
+ fixed: z.ZodString;
5480
+ }, z.core.$strict>, z.ZodObject<{
5481
+ value: z.ZodString;
5482
+ }, z.core.$strict>]>;
5483
+ requestFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
5484
+ payload: z.ZodRecord<z.ZodString, z.ZodString>;
5485
+ fixed: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>>;
5486
+ read: z.ZodObject<{
5487
+ revision: z.ZodString;
5488
+ body: z.ZodString;
5489
+ subject: z.ZodOptional<z.ZodString>;
5490
+ to: z.ZodOptional<z.ZodString>;
5491
+ cc: z.ZodOptional<z.ZodString>;
5492
+ bcc: z.ZodOptional<z.ZodString>;
5493
+ attachments: z.ZodOptional<z.ZodString>;
5494
+ }, z.core.$strict>;
5495
+ }, z.core.$strict>>;
5496
+ }, z.core.$strict>;
5497
+ display: z.ZodOptional<z.ZodObject<{
5498
+ bodyFormat: z.ZodOptional<z.ZodLiteral<"mrkdwn">>;
5499
+ replyField: z.ZodOptional<z.ZodString>;
5500
+ replyLabel: z.ZodOptional<z.ZodString>;
5501
+ facts: z.ZodOptional<z.ZodArray<z.ZodObject<{
5502
+ label: z.ZodString;
5503
+ field: z.ZodString;
5504
+ }, z.core.$strict>>>;
5505
+ }, z.core.$strict>>;
5423
5506
  globalId: z.ZodString;
5424
- kind: z.ZodEnum<{
5425
- message: "message";
5426
- change: "change";
5427
- action: "action";
5428
- access: "access";
5429
- }>;
5507
+ moduleId: z.ZodString;
5508
+ authService: z.ZodOptional<z.ZodString>;
5430
5509
  }, z.core.$strict>>>;
5431
5510
  kayAppDataSources: z.ZodOptional<z.ZodArray<z.ZodObject<{
5432
5511
  localId: z.ZodString;
@@ -2635,8 +2635,20 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2635
2635
  * registers the named function on any such scheme, its own client's included, and the SDK refuses a
2636
2636
  * plugin whose lookup and manifest disagree. An own-client (`pkce`) scheme may carry the
2637
2637
  * `clientSecret` that goes with its `clientId`. A plugin with an `oauth2` sign-in declares ^0.26.3.
2638
+ *
2639
+ * 0.27.0 makes a message approval card manifest data (#14574). `approvalTypes` declares the card's
2640
+ * facts and forms, and Bonsai draws it with the module's `describeOperation` and sends it with its
2641
+ * `write`. `app.approvals`, its `prepare`, `finalize` and `resolveResource` are gone, and a write can
2642
+ * refuse in the person's words with `UriProviderError.refusalMessage`. No plugin outside this repo
2643
+ * declared a card, so 0.26.3 stays served. A plugin that declares a card declares ^0.27.0.
2644
+ *
2645
+ * 0.27.1 lets a manifest URI module name the exact sign-in scheme its calls use, as a tool can
2646
+ * (#14928): `authScheme`, a scheme of the module's `authService`, local or another plugin's. A
2647
+ * hosted module's code and manifest must agree on it, and the daemon reads it to find an
2648
+ * external-CLI scheme without running the module. A module that runs in the daemon is unchanged,
2649
+ * so this is additive; a plugin whose manifest sets `authScheme` declares ^0.27.1.
2638
2650
  */
2639
- declare const KAY_PLUGIN_SDK_VERSION: "0.26.3";
2651
+ declare const KAY_PLUGIN_SDK_VERSION: "0.27.1";
2640
2652
 
2641
2653
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2642
2654
 
@@ -11198,6 +11210,8 @@ export declare class UriProviderError extends UriError {
11198
11210
  readonly retryAfterMs?: number;
11199
11211
  /** See {@link UriProviderErrorOptions.effect}. */
11200
11212
  readonly effect?: "none";
11213
+ /** See {@link UriProviderErrorOptions.refusalMessage}. */
11214
+ readonly refusalMessage?: string;
11201
11215
  constructor(options: UriProviderErrorOptions);
11202
11216
  }
11203
11217
 
@@ -11220,6 +11234,11 @@ export declare interface UriProviderErrorOptions {
11220
11234
  * earlier request may have changed something.
11221
11235
  */
11222
11236
  readonly effect?: "none";
11237
+ /**
11238
+ * What to tell the person when a write they approved was refused, in their words. Only with
11239
+ * `effect: "none"`: it is the plugin saying nothing happened and why.
11240
+ */
11241
+ readonly refusalMessage?: string;
11223
11242
  }
11224
11243
 
11225
11244
  export declare interface UriResolveContext {
package/dist/kay-agent.js CHANGED
@@ -388,6 +388,8 @@ var UriProviderError = class extends UriError {
388
388
  retryAfterMs;
389
389
  /** See {@link UriProviderErrorOptions.effect}. */
390
390
  effect;
391
+ /** See {@link UriProviderErrorOptions.refusalMessage}. */
392
+ refusalMessage;
391
393
  constructor(options) {
392
394
  super(options.message);
393
395
  this.name = "UriProviderError";
@@ -408,6 +410,12 @@ var UriProviderError = class extends UriError {
408
410
  }
409
411
  if (options.effect !== void 0)
410
412
  this.effect = options.effect;
413
+ if (options.refusalMessage !== void 0) {
414
+ if (options.effect !== "none") {
415
+ throw new TypeError('refusalMessage requires effect: "none".');
416
+ }
417
+ this.refusalMessage = options.refusalMessage;
418
+ }
411
419
  }
412
420
  };
413
421
  var UriNotFoundError = class extends UriError {
package/dist/kay-app.d.ts CHANGED
@@ -2,6 +2,10 @@ import { pathToFileURL } from 'node:url';
2
2
  import type { StatementSync } from 'node:sqlite';
3
3
  import { z } from 'zod';
4
4
 
5
+ export declare interface AccessApprovalContext {
6
+ readonly signal: AbortSignal;
7
+ }
8
+
5
9
  export declare interface AccessApprovalInput {
6
10
  readonly uri: string;
7
11
  readonly content: Record<string, unknown>;
@@ -27,7 +31,7 @@ export declare interface AccessApprovalTypeDefinition {
27
31
  readonly prepare: (input: AccessApprovalInput) => PreparedAccessApproval | undefined;
28
32
  readonly finalize: (input: {
29
33
  readonly prepared: PreparedAccessApproval;
30
- }, ctx: ApprovalTypeContext) => Promise<FinalizedAccessApproval>;
34
+ }, ctx: AccessApprovalContext) => Promise<FinalizedAccessApproval>;
31
35
  }
32
36
 
33
37
  declare const AdapterPlacement: z.ZodEnum<{
@@ -142,9 +146,6 @@ declare const AnthropicMessagesCompatSchema: Type.TObject<{
142
146
  /** Creates a Any type. */
143
147
  declare function Any(options?: TSchemaOptions): TAny;
144
148
 
145
- /** Every approval type kind, for registration and storage boundaries. */
146
- export declare type AnyApprovalTypeDefinition = MessageApprovalTypeDefinition | AccessApprovalTypeDefinition;
147
-
148
149
  declare type Api = KnownApi | (string & {});
149
150
 
150
151
  export declare const ApprovalOrigin: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -157,24 +158,6 @@ export declare const ApprovalOrigin: z.ZodDiscriminatedUnion<[z.ZodObject<{
157
158
 
158
159
  export declare type ApprovalOrigin = z.infer<typeof ApprovalOrigin>;
159
160
 
160
- export declare interface ApprovalTypeContext {
161
- readonly signal: AbortSignal;
162
- readonly read?: (uri: string) => Promise<{
163
- readonly content: string | Uint8Array;
164
- }>;
165
- readonly edit?: (uri: string, patch: unknown, options: {
166
- readonly signal: AbortSignal;
167
- }) => Promise<{
168
- readonly resource: unknown;
169
- }>;
170
- readonly report?: (stage: "edit" | "verify", attributes: Readonly<Record<string, string>>) => void;
171
- }
172
-
173
- /** Legacy name for a message approval type; message-only plugins keep compiling against it. */
174
- export declare type ApprovalTypeDefinition = MessageApprovalTypeDefinition;
175
-
176
- export declare type ApprovalTypeResolver = (provider: string) => RegisteredApprovalType | undefined;
177
-
178
161
  /** Creates an Array type. */
179
162
  declare function _Array_<Type extends TSchema>(items: Type, options?: TArrayOptions): TArray<Type>;
180
163
 
@@ -372,10 +355,6 @@ declare type AvailabilityFactsMessage = CustomMessage<AvailabilityFactsDetails>
372
355
  readonly display: true;
373
356
  };
374
357
 
375
- declare type AvailableDraft = Extract<UiMessageDraftResource, {
376
- status: "available";
377
- }>;
378
-
379
358
  declare const BACKGROUND_TASK_RESULT_CUSTOM_TYPE = "background_task_result";
380
359
 
381
360
  declare interface BackgroundTaskAdoptOptions {
@@ -1552,13 +1531,10 @@ declare const FileExtensionToken: z.ZodString;
1552
1531
 
1553
1532
  declare type FileExtensionToken = z.infer<typeof FileExtensionToken>;
1554
1533
 
1555
- export declare type FinalizedAccessApproval = FinalizedMessageApproval;
1556
-
1557
- export declare type FinalizedMessageApproval = {
1534
+ export declare type FinalizedAccessApproval = {
1558
1535
  readonly status: "ready";
1559
1536
  readonly uri: string;
1560
1537
  readonly content: Record<string, unknown>;
1561
- readonly resourceChanged?: true;
1562
1538
  } | {
1563
1539
  readonly status: "failed";
1564
1540
  readonly message: string;
@@ -2630,8 +2606,20 @@ declare const KAY_PLUGIN_PROTOCOL_VERSION: "kay.plugin.v1";
2630
2606
  * registers the named function on any such scheme, its own client's included, and the SDK refuses a
2631
2607
  * plugin whose lookup and manifest disagree. An own-client (`pkce`) scheme may carry the
2632
2608
  * `clientSecret` that goes with its `clientId`. A plugin with an `oauth2` sign-in declares ^0.26.3.
2609
+ *
2610
+ * 0.27.0 makes a message approval card manifest data (#14574). `approvalTypes` declares the card's
2611
+ * facts and forms, and Bonsai draws it with the module's `describeOperation` and sends it with its
2612
+ * `write`. `app.approvals`, its `prepare`, `finalize` and `resolveResource` are gone, and a write can
2613
+ * refuse in the person's words with `UriProviderError.refusalMessage`. No plugin outside this repo
2614
+ * declared a card, so 0.26.3 stays served. A plugin that declares a card declares ^0.27.0.
2615
+ *
2616
+ * 0.27.1 lets a manifest URI module name the exact sign-in scheme its calls use, as a tool can
2617
+ * (#14928): `authScheme`, a scheme of the module's `authService`, local or another plugin's. A
2618
+ * hosted module's code and manifest must agree on it, and the daemon reads it to find an
2619
+ * external-CLI scheme without running the module. A module that runs in the daemon is unchanged,
2620
+ * so this is additive; a plugin whose manifest sets `authScheme` declares ^0.27.1.
2633
2621
  */
2634
- declare const KAY_PLUGIN_SDK_VERSION: "0.26.3";
2622
+ declare const KAY_PLUGIN_SDK_VERSION: "0.27.1";
2635
2623
 
2636
2624
  declare const KAY_PLUGIN_TARGET_NAMES: readonly ["kay.agent", "kay.app", "kay.ui"];
2637
2625
 
@@ -3151,11 +3139,6 @@ export declare interface KayAppAgents {
3151
3139
  }): Promise<KayAppSessionRunOutcome>;
3152
3140
  }
3153
3141
 
3154
- export declare interface KayAppApprovals {
3155
- /** Register a declared type exactly once during activation. */
3156
- registerType(localId: string, definition: AnyApprovalTypeDefinition): void;
3157
- }
3158
-
3159
3142
  export declare interface KayAppArtifact {
3160
3143
  readonly uri: string;
3161
3144
  readonly kind: string;
@@ -5024,7 +5007,6 @@ export declare interface KayAppPhaseShiftSessionEvent extends KayAppSessionEvent
5024
5007
  export declare interface KayAppPluginApi {
5025
5008
  /** This plugin's canonical id (already validated by the host registry). */
5026
5009
  readonly id: string;
5027
- readonly approvals: KayAppApprovals;
5028
5010
  /** Register app-lifetime cleanup for plugin-owned processes, sockets, watchers, or timers. */
5029
5011
  readonly lifecycle: KayAppLifecycle;
5030
5012
  /**
@@ -8722,175 +8704,12 @@ export declare namespace Memory {
8722
8704
 
8723
8705
  declare type Message = SystemMessage | UserMessage | AssistantMessage | ToolResultMessage;
8724
8706
 
8725
- export declare const MESSAGE_DRAFT_BODY_MAX = 20000;
8726
-
8727
- export declare const MESSAGE_DRAFT_SUBJECT_MAX = 300;
8728
-
8729
- export declare type MessageApprovalContent = AvailableDraft["content"] | {
8730
- readonly kind: "inline-email";
8731
- readonly to: readonly string[];
8732
- readonly cc?: readonly string[];
8733
- readonly bcc?: readonly string[];
8734
- readonly subject: string;
8735
- readonly body: string;
8736
- } | {
8737
- readonly kind: "inline-chat";
8738
- readonly provider: "slack";
8739
- readonly conversationUri: string;
8740
- readonly body: string;
8741
- };
8742
-
8743
- export declare interface MessageApprovalInput {
8744
- readonly content: MessageApprovalContent;
8745
- readonly request: UiMessageDraftDeliveryRequest | UiMessageDraftInlineDeliveryRequest;
8746
- /** Unqualified provider URI after host account validation. */
8747
- readonly uri: string;
8748
- readonly resource?: AvailableDraft;
8749
- }
8750
-
8751
- /** A fixed delivery refusal from pure preparation; safe across separately bundled SDK copies. */
8752
- export declare class MessageApprovalPreparationError extends Error {
8753
- readonly reason: "invalid-destination" | "invalid-content";
8754
- constructor(reason: "invalid-destination" | "invalid-content");
8755
- }
8756
-
8757
- export declare interface MessageApprovalTypeDefinition {
8758
- readonly kind: "message";
8759
- readonly provider: string;
8760
- readonly moduleId: string;
8761
- readonly unknownMessage: string;
8762
- readonly fields: {
8763
- readonly body: {
8764
- readonly key: string;
8765
- readonly max: number;
8766
- };
8767
- readonly subject?: {
8768
- readonly key: string;
8769
- readonly max: number;
8770
- };
8771
- };
8772
- readonly presentation: {
8773
- readonly showAccount: boolean;
8774
- readonly recipient: "person" | "target";
8775
- };
8776
- /** Pure preparation; does not execute the reviewed operation. Async because the host may call it across a process boundary. */
8777
- readonly prepare: (input: MessageApprovalInput) => Promise<PreparedMessageApproval | undefined>;
8778
- readonly finalize: (input: {
8779
- readonly prepared: PreparedMessageApproval;
8780
- readonly failure?: {
8781
- readonly error: unknown;
8782
- };
8783
- readonly body: string;
8784
- readonly subject?: string;
8785
- }, ctx: ApprovalTypeContext) => Promise<FinalizedMessageApproval>;
8786
- /** Finds a saved draft this provider keeps. Omit it when the provider keeps none. */
8787
- readonly resolveResource?: (uri: string, ctx: ApprovalTypeContext) => Promise<UiMessageDraftResource | undefined>;
8788
- }
8789
-
8790
- /** Review-specific routing inputs. The host must resolve the stable account and validate the provider route. */
8791
- declare const messageDraftDeliveryRequestSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
8792
- provider: z.ZodLiteral<"gmail">;
8793
- accountId: z.ZodString;
8794
- threadId: z.ZodOptional<z.ZodString>;
8795
- inReplyTo: z.ZodOptional<z.ZodString>;
8796
- references: z.ZodOptional<z.ZodArray<z.ZodString>>;
8797
- }, z.core.$strict>, z.ZodObject<{
8798
- provider: z.ZodLiteral<"slack">;
8799
- accountId: z.ZodString;
8800
- threadTs: z.ZodOptional<z.ZodString>;
8801
- }, z.core.$strict>, z.ZodObject<{
8802
- provider: z.ZodLiteral<"teams">;
8803
- accountId: z.ZodString;
8804
- replyTo: z.ZodOptional<z.ZodString>;
8805
- }, z.core.$strict>], "provider">;
8806
-
8807
8707
  /**
8808
- * The routing an INLINE card may ask the host for: Gmail, whose recipients are the card's own
8809
- * props, or Slack, whose request names its conversation. An inline Teams card names no
8810
- * destination the host could bind to the press, so it keeps the agent's own write.
8708
+ * A message approval card's facts as Bonsai resolves them from the plugin's manifest. A card runs
8709
+ * no card-specific plugin code: it is drawn with the module's `describeOperation` and sent with its
8710
+ * `write`.
8811
8711
  */
8812
- declare const messageDraftInlineDeliveryRequestSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
8813
- provider: z.ZodLiteral<"gmail">;
8814
- accountId: z.ZodString;
8815
- threadId: z.ZodOptional<z.ZodString>;
8816
- inReplyTo: z.ZodOptional<z.ZodString>;
8817
- references: z.ZodOptional<z.ZodArray<z.ZodString>>;
8818
- }, z.core.$strict>, z.ZodObject<{
8819
- provider: z.ZodLiteral<"slack">;
8820
- accountId: z.ZodString;
8821
- conversationUri: z.ZodString;
8822
- threadTs: z.ZodOptional<z.ZodString>;
8823
- }, z.core.$strict>], "provider">;
8824
-
8825
- /** Immutable display evidence, not an approval or an editable copy of the draft. */
8826
- export declare const messageDraftResourceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
8827
- status: z.ZodLiteral<"available">;
8828
- draftUri: z.ZodString;
8829
- revision: z.ZodString;
8830
- content: z.ZodDiscriminatedUnion<[z.ZodObject<{
8831
- kind: z.ZodLiteral<"email">;
8832
- to: z.ZodArray<z.ZodString>;
8833
- cc: z.ZodOptional<z.ZodArray<z.ZodString>>;
8834
- bcc: z.ZodOptional<z.ZodArray<z.ZodString>>;
8835
- subject: z.ZodString;
8836
- bodyMarkdown: z.ZodString;
8837
- bodyFormat: z.ZodOptional<z.ZodLiteral<"plain">>;
8838
- attachments: z.ZodOptional<z.ZodArray<z.ZodString>>;
8839
- }, z.core.$strict>, z.ZodObject<{
8840
- kind: z.ZodLiteral<"chat">;
8841
- provider: z.ZodEnum<{
8842
- slack: "slack";
8843
- teams: "teams";
8844
- }>;
8845
- conversationUri: z.ZodOptional<z.ZodString>;
8846
- bodyMarkdown: z.ZodString;
8847
- }, z.core.$strict>], "kind">;
8848
- delivery: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
8849
- status: z.ZodLiteral<"ready">;
8850
- sessionId: z.ZodString;
8851
- request: z.ZodUnion<readonly [z.ZodDiscriminatedUnion<[z.ZodObject<{
8852
- provider: z.ZodLiteral<"gmail">;
8853
- accountId: z.ZodString;
8854
- threadId: z.ZodOptional<z.ZodString>;
8855
- inReplyTo: z.ZodOptional<z.ZodString>;
8856
- references: z.ZodOptional<z.ZodArray<z.ZodString>>;
8857
- }, z.core.$strict>, z.ZodObject<{
8858
- provider: z.ZodLiteral<"slack">;
8859
- accountId: z.ZodString;
8860
- threadTs: z.ZodOptional<z.ZodString>;
8861
- }, z.core.$strict>, z.ZodObject<{
8862
- provider: z.ZodLiteral<"teams">;
8863
- accountId: z.ZodString;
8864
- replyTo: z.ZodOptional<z.ZodString>;
8865
- }, z.core.$strict>], "provider">, z.ZodObject<{
8866
- provider: z.ZodLiteral<"slack">;
8867
- accountId: z.ZodString;
8868
- conversationUri: z.ZodString;
8869
- threadTs: z.ZodOptional<z.ZodString>;
8870
- }, z.core.$strict>]>;
8871
- accountName: z.ZodOptional<z.ZodString>;
8872
- destination: z.ZodOptional<z.ZodString>;
8873
- writeUri: z.ZodString;
8874
- }, z.core.$strict>, z.ZodObject<{
8875
- status: z.ZodLiteral<"unavailable">;
8876
- reason: z.ZodEnum<{
8877
- "missing-context": "missing-context";
8878
- "account-unavailable": "account-unavailable";
8879
- "invalid-destination": "invalid-destination";
8880
- "invalid-content": "invalid-content";
8881
- "unnamed-destination": "unnamed-destination";
8882
- }>;
8883
- }, z.core.$strict>], "status">>;
8884
- }, z.core.$strict>, z.ZodObject<{
8885
- status: z.ZodEnum<{
8886
- unavailable: "unavailable";
8887
- missing: "missing";
8888
- invalid: "invalid";
8889
- "unsupported-version": "unsupported-version";
8890
- "too-large": "too-large";
8891
- }>;
8892
- draftUri: z.ZodString;
8893
- }, z.core.$strict>], "status">;
8712
+ export declare type MessageApprovalFacts = ResolvedKayAppApprovalType;
8894
8713
 
8895
8714
  declare interface MessageEntry extends EntryBase {
8896
8715
  type: "message";
@@ -9884,13 +9703,6 @@ export declare interface PreparedAccessApproval {
9884
9703
  readonly binding?: unknown;
9885
9704
  }
9886
9705
 
9887
- export declare interface PreparedMessageApproval {
9888
- readonly uri: string;
9889
- readonly content: Record<string, unknown>;
9890
- /** Provider-private state retained only in host memory. */
9891
- readonly binding?: unknown;
9892
- }
9893
-
9894
9706
  declare const Properties: (input: string) => [unknown, string] | [];
9895
9707
 
9896
9708
  declare function PropertiesMapping(input: [unknown, unknown, unknown]): unknown;
@@ -9959,8 +9771,6 @@ export declare interface QualifiedApprovalTypeId {
9959
9771
  readonly localId: string;
9960
9772
  }
9961
9773
 
9962
- export declare type QualifiedApprovalTypeResolver = (id: QualifiedApprovalTypeId) => ResolvedApprovalType | undefined;
9963
-
9964
9774
  export declare interface RawResource {
9965
9775
  readonly uri: string;
9966
9776
  readonly content: string | Uint8Array;
@@ -10126,18 +9936,18 @@ declare function refineWebSessionScopeConfined(webSession: {
10126
9936
  };
10127
9937
  }, ctx: z.RefinementCtx): void;
10128
9938
 
10129
- export declare interface RegisteredApprovalType<D extends AnyApprovalTypeDefinition = MessageApprovalTypeDefinition> {
10130
- readonly pluginId: string;
10131
- readonly localId: string;
10132
- readonly definition: D;
10133
- }
10134
-
10135
9939
  export declare interface RegisteredHostApprovalType {
10136
9940
  readonly hostId: string;
10137
9941
  readonly localId: string;
10138
9942
  readonly definition: AccessApprovalTypeDefinition;
10139
9943
  }
10140
9944
 
9945
+ export declare interface RegisteredMessageApprovalFacts {
9946
+ readonly pluginId: string;
9947
+ readonly localId: string;
9948
+ readonly definition: MessageApprovalFacts;
9949
+ }
9950
+
10141
9951
  declare const RegistrableDomain: z.ZodString;
10142
9952
 
10143
9953
  declare type RegistrableDomain = z.infer<typeof RegistrableDomain>;
@@ -10219,8 +10029,6 @@ declare interface RequiresAuth {
10219
10029
  */
10220
10030
  export declare function requireWriteContent(payload: UriPayload | Uint8Array | undefined, uri: string): UriPayload;
10221
10031
 
10222
- export declare type ResolvedApprovalType = RegisteredApprovalType<AnyApprovalTypeDefinition> | RegisteredHostApprovalType;
10223
-
10224
10032
  /**
10225
10033
  * The credential the host resolved for one call to plugin code that declares `requiresAuth`: a URI
10226
10034
  * verb (`ctx.auth.credential`), a tool (`ctx.credential`) or a search provider (`ctx.credential`).
@@ -10239,6 +10047,85 @@ declare interface ResolvedCredential {
10239
10047
  readonly fields?: Readonly<Record<string, string>>;
10240
10048
  }
10241
10049
 
10050
+ declare const ResolvedKayAppApprovalType: z.ZodObject<{
10051
+ kind: z.ZodLiteral<"message">;
10052
+ localId: z.ZodString;
10053
+ provider: z.ZodString;
10054
+ unknownMessage: z.ZodString;
10055
+ fields: z.ZodObject<{
10056
+ body: z.ZodObject<{
10057
+ key: z.ZodString;
10058
+ max: z.ZodNumber;
10059
+ }, z.core.$strict>;
10060
+ subject: z.ZodOptional<z.ZodObject<{
10061
+ key: z.ZodString;
10062
+ max: z.ZodNumber;
10063
+ }, z.core.$strict>>;
10064
+ }, z.core.$strict>;
10065
+ presentation: z.ZodObject<{
10066
+ showAccount: z.ZodBoolean;
10067
+ recipient: z.ZodEnum<{
10068
+ target: "target";
10069
+ person: "person";
10070
+ }>;
10071
+ }, z.core.$strict>;
10072
+ forms: z.ZodObject<{
10073
+ inline: z.ZodOptional<z.ZodObject<{
10074
+ uri: z.ZodUnion<readonly [z.ZodObject<{
10075
+ fixed: z.ZodString;
10076
+ }, z.core.$strict>, z.ZodObject<{
10077
+ value: z.ZodString;
10078
+ }, z.core.$strict>]>;
10079
+ requestFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
10080
+ payload: z.ZodRecord<z.ZodString, z.ZodString>;
10081
+ fixed: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>>;
10082
+ }, z.core.$strict>>;
10083
+ saved: z.ZodOptional<z.ZodObject<{
10084
+ uri: z.ZodUnion<readonly [z.ZodObject<{
10085
+ fixed: z.ZodString;
10086
+ }, z.core.$strict>, z.ZodObject<{
10087
+ value: z.ZodString;
10088
+ }, z.core.$strict>]>;
10089
+ requestFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
10090
+ payload: z.ZodRecord<z.ZodString, z.ZodString>;
10091
+ fixed: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>>;
10092
+ }, z.core.$strict>>;
10093
+ stored: z.ZodOptional<z.ZodObject<{
10094
+ uri: z.ZodUnion<readonly [z.ZodObject<{
10095
+ fixed: z.ZodString;
10096
+ }, z.core.$strict>, z.ZodObject<{
10097
+ value: z.ZodString;
10098
+ }, z.core.$strict>]>;
10099
+ requestFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
10100
+ payload: z.ZodRecord<z.ZodString, z.ZodString>;
10101
+ fixed: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>>;
10102
+ read: z.ZodObject<{
10103
+ revision: z.ZodString;
10104
+ body: z.ZodString;
10105
+ subject: z.ZodOptional<z.ZodString>;
10106
+ to: z.ZodOptional<z.ZodString>;
10107
+ cc: z.ZodOptional<z.ZodString>;
10108
+ bcc: z.ZodOptional<z.ZodString>;
10109
+ attachments: z.ZodOptional<z.ZodString>;
10110
+ }, z.core.$strict>;
10111
+ }, z.core.$strict>>;
10112
+ }, z.core.$strict>;
10113
+ display: z.ZodOptional<z.ZodObject<{
10114
+ bodyFormat: z.ZodOptional<z.ZodLiteral<"mrkdwn">>;
10115
+ replyField: z.ZodOptional<z.ZodString>;
10116
+ replyLabel: z.ZodOptional<z.ZodString>;
10117
+ facts: z.ZodOptional<z.ZodArray<z.ZodObject<{
10118
+ label: z.ZodString;
10119
+ field: z.ZodString;
10120
+ }, z.core.$strict>>>;
10121
+ }, z.core.$strict>>;
10122
+ globalId: z.ZodString;
10123
+ moduleId: z.ZodString;
10124
+ authService: z.ZodOptional<z.ZodString>;
10125
+ }, z.core.$strict>;
10126
+
10127
+ declare type ResolvedKayAppApprovalType = z.infer<typeof ResolvedKayAppApprovalType>;
10128
+
10242
10129
  /** Match remaining characters in the buffer until end. If no characters are in buffer, no match */
10243
10130
  declare function Rest<Input extends string>(input: Input): TRest<Input>;
10244
10131
 
@@ -15321,12 +15208,6 @@ declare type UiActionMessage = CustomMessage<UiActionDetails> & {
15321
15208
  readonly display: true;
15322
15209
  };
15323
15210
 
15324
- declare type UiMessageDraftDeliveryRequest = z.infer<typeof messageDraftDeliveryRequestSchema>;
15325
-
15326
- declare type UiMessageDraftInlineDeliveryRequest = z.infer<typeof messageDraftInlineDeliveryRequestSchema>;
15327
-
15328
- export declare type UiMessageDraftResource = z.infer<typeof messageDraftResourceSchema>;
15329
-
15330
15211
  /** Applies a Uncapitalize action to the given type. */
15331
15212
  declare function Uncapitalize_2<Type extends TSchema>(type: Type, options?: TSchemaOptions): TUncapitalize<Type>;
15332
15213
 
@@ -16069,6 +15950,8 @@ export declare class UriProviderError extends UriError {
16069
15950
  readonly retryAfterMs?: number;
16070
15951
  /** See {@link UriProviderErrorOptions.effect}. */
16071
15952
  readonly effect?: "none";
15953
+ /** See {@link UriProviderErrorOptions.refusalMessage}. */
15954
+ readonly refusalMessage?: string;
16072
15955
  constructor(options: UriProviderErrorOptions);
16073
15956
  }
16074
15957
 
@@ -16091,6 +15974,11 @@ export declare interface UriProviderErrorOptions {
16091
15974
  * earlier request may have changed something.
16092
15975
  */
16093
15976
  readonly effect?: "none";
15977
+ /**
15978
+ * What to tell the person when a write they approved was refused, in their words. Only with
15979
+ * `effect: "none"`: it is the plugin saying nothing happened and why.
15980
+ */
15981
+ readonly refusalMessage?: string;
16094
15982
  }
16095
15983
 
16096
15984
  /**
package/dist/kay-app.js CHANGED
@@ -299,6 +299,8 @@ var UriProviderError = class extends UriError {
299
299
  retryAfterMs;
300
300
  /** See {@link UriProviderErrorOptions.effect}. */
301
301
  effect;
302
+ /** See {@link UriProviderErrorOptions.refusalMessage}. */
303
+ refusalMessage;
302
304
  constructor(options) {
303
305
  super(options.message);
304
306
  this.name = "UriProviderError";
@@ -319,6 +321,12 @@ var UriProviderError = class extends UriError {
319
321
  }
320
322
  if (options.effect !== void 0)
321
323
  this.effect = options.effect;
324
+ if (options.refusalMessage !== void 0) {
325
+ if (options.effect !== "none") {
326
+ throw new TypeError('refusalMessage requires effect: "none".');
327
+ }
328
+ this.refusalMessage = options.refusalMessage;
329
+ }
322
330
  }
323
331
  };
324
332
  var UriNotFoundError = class extends UriError {
@@ -537,189 +545,6 @@ function isRetryable(result) {
537
545
  return result.status === "not-ready";
538
546
  }
539
547
 
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
548
  // packages/plugin-sdk/dist/kay-app/auth.js
724
549
  var KayAppCredentialRejectedError = class extends Error {
725
550
  name = "KayAppCredentialRejectedError";
@@ -1072,9 +897,6 @@ export {
1072
897
  KayAppCredentialRejectedError,
1073
898
  KayAppWorkflowFailure,
1074
899
  MAX_CHOICE_LABELS,
1075
- MESSAGE_DRAFT_BODY_MAX,
1076
- MESSAGE_DRAFT_SUBJECT_MAX,
1077
- MessageApprovalPreparationError,
1078
900
  SIGNAL_TIME_MAX_MS,
1079
901
  STORED_TRANSCRIPT_MESSAGE_FILTER,
1080
902
  STORED_TRANSCRIPT_MESSAGE_KINDS,
@@ -1094,7 +916,6 @@ export {
1094
916
  failedRunCause,
1095
917
  invalidObservation,
1096
918
  isRetryable,
1097
- messageDraftResourceSchema,
1098
919
  parseLineSelector,
1099
920
  parseStoredTranscriptKindFilter,
1100
921
  pathToFileURL,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaklabs-ai/plugin-sdk",
3
- "version": "0.26.3",
3
+ "version": "0.27.1",
4
4
  "description": "The Kay plugin SDK — types and helpers for authoring a Kay directory plugin.",
5
5
  "author": "YakLabs",
6
6
  "type": "module",