@agent-native/core 0.214.0 → 0.216.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/dist/action.js +54 -1
  2. package/dist/agent/actions/disconnect-chatgpt-subscription.js +5 -0
  3. package/dist/agent/actions/get-agentkit-capabilities.js +3 -3
  4. package/dist/agent/actions/manage-builder-connection.js +5 -0
  5. package/dist/agent/actions/manage-provider-key-policy.js +5 -0
  6. package/dist/agent/actions/manage-provider-models.js +5 -0
  7. package/dist/agent/actions/manage-service-providers.js +5 -0
  8. package/dist/agent/actions/select-chatgpt-subscription-account.js +5 -0
  9. package/dist/agent/context-xray/actions/context-evict.js +5 -0
  10. package/dist/agent/context-xray/actions/context-pin.js +5 -0
  11. package/dist/agent/context-xray/actions/context-report.js +5 -0
  12. package/dist/agent/context-xray/actions/context-restore.js +5 -0
  13. package/dist/agent/execution-fence.d.ts +1 -0
  14. package/dist/agent/execution-fence.js +5 -0
  15. package/dist/agent/production-agent.d.ts +35 -2
  16. package/dist/agent/production-agent.js +629 -32
  17. package/dist/agent/run-manager.d.ts +2 -0
  18. package/dist/agent/run-manager.js +397 -115
  19. package/dist/agent/run-slot-lock.d.ts +2 -0
  20. package/dist/agent/run-slot-lock.js +6 -0
  21. package/dist/agent/run-store.d.ts +5 -0
  22. package/dist/agent/run-store.js +423 -156
  23. package/dist/agent/thread-data-builder.js +27 -5
  24. package/dist/agent/types.d.ts +6 -12
  25. package/dist/agentkit/capabilities.d.ts +1 -1
  26. package/dist/application-state/store.d.ts +5 -0
  27. package/dist/application-state/store.js +26 -0
  28. package/dist/chat-threads/schema-migrations.js +17 -0
  29. package/dist/chat-threads/store.d.ts +21 -1
  30. package/dist/chat-threads/store.js +223 -41
  31. package/dist/cli/skills-content/turn-into-app-skill.d.ts +1 -1
  32. package/dist/cli/skills-content/turn-into-app-skill.js +20 -18
  33. package/dist/cli/templates-meta.js +14 -0
  34. package/dist/client/analytics.js +167 -17
  35. package/dist/client/chat/agentkit-agent-native.js +79 -3
  36. package/dist/client/chat/agentkit-protocol.js +80 -42
  37. package/dist/client/chat/runtime.d.ts +5 -1
  38. package/dist/client/chat/runtime.js +46 -3
  39. package/dist/client/consent.d.ts +36 -0
  40. package/dist/client/consent.js +283 -0
  41. package/dist/client/review/use-review.d.ts +2 -0
  42. package/dist/client/review/use-review.js +28 -1
  43. package/dist/client/sharing/useResourceAccessGate.d.ts +3 -2
  44. package/dist/client/sharing/useResourceAccessGate.js +9 -1
  45. package/dist/client/use-chat-thread-list.d.ts +2 -0
  46. package/dist/client/use-chat-thread-list.js +12 -2
  47. package/dist/client/use-chat-threads.d.ts +1 -0
  48. package/dist/client/use-chat-threads.js +2 -0
  49. package/dist/collab/awareness.d.ts +2 -2
  50. package/dist/collab/routes.d.ts +2 -2
  51. package/dist/collab/struct-routes.d.ts +1 -1
  52. package/dist/connections/catalog.d.ts +5 -5
  53. package/dist/connections/catalog.js +22 -3
  54. package/dist/data-widgets/index.d.ts +36 -2
  55. package/dist/data-widgets/index.js +94 -6
  56. package/dist/db/migrations.js +4 -1
  57. package/dist/db/schema-snapshot.generated.js +8 -1
  58. package/dist/feature-flags/actions/set-feature-flag.js +5 -0
  59. package/dist/feature-flags/index.d.ts +1 -1
  60. package/dist/feature-flags/index.js +1 -1
  61. package/dist/feature-flags/store.d.ts +12 -0
  62. package/dist/feature-flags/store.js +79 -7
  63. package/dist/file-upload/actions/manage-file-storage.js +5 -0
  64. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  65. package/dist/file-upload/actions/upload-image.js +5 -0
  66. package/dist/history/actions/create-resource-version.js +5 -0
  67. package/dist/history/actions/restore-resource-version.js +5 -0
  68. package/dist/ingestion/index.d.ts +1 -1
  69. package/dist/ingestion/index.js +1 -1
  70. package/dist/ingestion/pptx.d.ts +11 -0
  71. package/dist/ingestion/pptx.js +81 -1
  72. package/dist/integrations/actions/manage-messaging-channel.js +5 -0
  73. package/dist/jobs/scheduler.js +17 -1
  74. package/dist/labs/actions/set-lab.js +5 -0
  75. package/dist/localization/actions/set-localization-preference.js +5 -0
  76. package/dist/observability/actions/save-observability-instruction-update.js +5 -0
  77. package/dist/observability/actions/save-observability-review-summary.js +5 -0
  78. package/dist/progress/routes.d.ts +1 -1
  79. package/dist/provider-api/actions/custom-provider-registration.d.ts +18 -18
  80. package/dist/provider-api/actions/provider-api.d.ts +14 -14
  81. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  82. package/dist/provider-api/index.js +9 -2
  83. package/dist/review/actions/consume-review-feedback.js +5 -0
  84. package/dist/review/actions/create-review-comment.js +5 -0
  85. package/dist/review/actions/delete-review-comment.js +5 -0
  86. package/dist/review/actions/react-to-review-comment.js +5 -0
  87. package/dist/review/actions/reply-review-comment.js +5 -0
  88. package/dist/review/actions/resolve-review-thread.js +5 -0
  89. package/dist/review/actions/send-review-thread-to-agent.js +5 -0
  90. package/dist/review/actions/set-review-status.js +5 -0
  91. package/dist/review/actions/set-review-thread-muted.js +5 -0
  92. package/dist/review/actions/set-review-thread-unread.js +5 -0
  93. package/dist/review/actions/set-review-threads-unread.js +5 -0
  94. package/dist/review/actions/update-review-comment-anchor.js +5 -0
  95. package/dist/review/actions/update-review-comment.js +5 -0
  96. package/dist/review/suggestions/actions.js +60 -21
  97. package/dist/review/suggestions/store.d.ts +2 -0
  98. package/dist/review/suggestions/store.js +28 -0
  99. package/dist/secrets/actions/delete-api-key.js +5 -0
  100. package/dist/secrets/routes.d.ts +6 -6
  101. package/dist/server/agent-chat/context-tools.js +63 -2
  102. package/dist/server/agent-chat-plugin.d.ts +2 -0
  103. package/dist/server/agent-chat-plugin.js +242 -54
  104. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  105. package/dist/server/agent-engine-default-model-route.d.ts +2 -2
  106. package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
  107. package/dist/server/application-state-maintenance.d.ts +2 -0
  108. package/dist/server/application-state-maintenance.js +2 -0
  109. package/dist/server/attribution.d.ts +14 -0
  110. package/dist/server/attribution.js +62 -2
  111. package/dist/server/auth.js +7 -0
  112. package/dist/server/consent-route.d.ts +41 -0
  113. package/dist/server/consent-route.js +102 -0
  114. package/dist/server/first-touch-route.d.ts +39 -0
  115. package/dist/server/first-touch-route.js +115 -0
  116. package/dist/server/index.d.ts +1 -0
  117. package/dist/server/index.js +1 -0
  118. package/dist/server/queued-submission-inbox-drain.d.ts +9 -0
  119. package/dist/server/queued-submission-inbox-drain.js +12 -0
  120. package/dist/server/request-origin.d.ts +6 -0
  121. package/dist/server/request-origin.js +12 -0
  122. package/dist/settings/org-settings.d.ts +2 -1
  123. package/dist/settings/org-settings.js +4 -1
  124. package/dist/settings/store.d.ts +8 -0
  125. package/dist/settings/store.js +14 -5
  126. package/dist/shared/consent.d.ts +31 -0
  127. package/dist/shared/consent.js +145 -0
  128. package/dist/shared/first-touch-persistence.d.ts +31 -0
  129. package/dist/shared/first-touch-persistence.js +53 -0
  130. package/dist/sharing/actions/set-resource-visibility.js +5 -0
  131. package/dist/sharing/actions/share-resource.js +5 -0
  132. package/dist/sharing/actions/unshare-resource.js +5 -0
  133. package/dist/templates/chat/.agents/skills/actions/references/action-fields.md +1 -1
  134. package/dist/templates/default/.agents/skills/actions/references/action-fields.md +1 -1
  135. package/dist/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +36 -80
  136. package/dist/templates/factory/.agents/skills/review-latest-feedback/references/channel-inventory.md +54 -16
  137. package/dist/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +50 -73
  138. package/dist/templates/headless/.agents/skills/actions/references/action-fields.md +1 -1
  139. package/dist/templates/workspace-core/.agents/skills/actions/references/action-fields.md +1 -1
  140. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +20 -18
  141. package/dist/triggers/actions/manage-automation.d.ts +1 -1
  142. package/dist/usage/actions/get-usage-metrics.js +27 -4
  143. package/dist/usage/actions/manage-usage-alert.js +5 -0
  144. package/dist/vite/client.js +8 -6
  145. package/dist/workspace-connections/actions/bulk-update-workspace-user-groups.js +5 -0
  146. package/dist/workspace-connections/actions/delete-workspace-user-group.js +5 -0
  147. package/dist/workspace-connections/actions/upsert-workspace-user-group.js +5 -0
  148. package/docs/content/actions-access-control.mdx +8 -8
  149. package/docs/content/actions-defining.mdx +9 -8
  150. package/docs/content/template-design-developers.mdx +9 -9
  151. package/docs/content/template-design-features.mdx +1 -3
  152. package/docs/content/turn-into-app.mdx +4 -0
  153. package/package.json +4 -3
  154. package/src/templates/chat/.agents/skills/actions/references/action-fields.md +1 -1
  155. package/src/templates/default/.agents/skills/actions/references/action-fields.md +1 -1
  156. package/src/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +36 -80
  157. package/src/templates/factory/.agents/skills/review-latest-feedback/references/channel-inventory.md +54 -16
  158. package/src/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +50 -73
  159. package/src/templates/headless/.agents/skills/actions/references/action-fields.md +1 -1
  160. package/src/templates/workspace-core/.agents/skills/actions/references/action-fields.md +1 -1
  161. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +20 -18
@@ -27,6 +27,11 @@ export default defineAction({
27
27
  ? "Cleared file storage credentials"
28
28
  : "Saved file storage settings",
29
29
  }),
30
+ mcpAnnotations: {
31
+ readOnlyHint: false,
32
+ destructiveHint: true,
33
+ openWorldHint: false,
34
+ },
30
35
  run: async ({ operation, ...values }, ctx) => operation === "clear"
31
36
  ? clearFileStorage(ctx)
32
37
  : { removedKeys: [], status: await saveFileStorage(ctx, values) },
@@ -42,8 +42,8 @@ declare const _default: import("../../action.js").ActionDefinition<{
42
42
  url: string;
43
43
  id: string;
44
44
  provider: string;
45
- error?: undefined;
46
45
  configured?: undefined;
46
+ error?: undefined;
47
47
  } | {
48
48
  url?: undefined;
49
49
  id?: undefined;
@@ -442,6 +442,11 @@ export default defineAction({
442
442
  .refine((args) => args.cleanup ? !!args.idempotencyKey : !!args.data || !!args.url, {
443
443
  message: "Either a data/url upload or an idempotencyKey cleanup is required.",
444
444
  }),
445
+ mcpAnnotations: {
446
+ readOnlyHint: false,
447
+ destructiveHint: true,
448
+ openWorldHint: true,
449
+ },
445
450
  run: async (args) => {
446
451
  const idempotencyKey = args.idempotencyKey?.trim();
447
452
  if (args.cleanup && idempotencyKey) {
@@ -13,6 +13,11 @@ const schema = z.object({
13
13
  export default defineAction({
14
14
  description: "Create a reusable version-history snapshot for a resource.",
15
15
  schema,
16
+ mcpAnnotations: {
17
+ readOnlyHint: false,
18
+ destructiveHint: false,
19
+ openWorldHint: false,
20
+ },
16
21
  run: async (args, ctx) => {
17
22
  const actionCtx = ctx;
18
23
  const access = await assertVersionedResourceAccess(args.resourceType, args.resourceId, actionCtx, "editor");
@@ -16,6 +16,11 @@ const schema = z
16
16
  export default defineAction({
17
17
  description: "Restore a resource from a reusable version-history snapshot.",
18
18
  schema,
19
+ mcpAnnotations: {
20
+ readOnlyHint: false,
21
+ destructiveHint: true,
22
+ openWorldHint: false,
23
+ },
19
24
  run: async (args, ctx) => {
20
25
  const actionCtx = ctx;
21
26
  const scope = {
@@ -1,7 +1,7 @@
1
1
  export { acquireIngestionLease, assertInventoryComplete, consumeIngestionBudget, createIngestionBudgetState, createIngestionCheckpoint, ingestionBudgetStopReason, releaseIngestionLease, renewIngestionLease, type AcquireIngestionLeaseInput, type AcquireIngestionLeaseResult, type IngestionBudgetLimits, type IngestionBudgetState, type IngestionBudgetStopReason, type IngestionCheckpoint, type IngestionLease, type IngestionPhase, } from "./orchestration.js";
2
2
  export { detectOfficeDocumentType, normalizeDocumentText, parseOfficeDocument, type OfficeDocumentAst, type OfficeDocumentParser, type OfficeDocumentPart, type OfficeDocumentType, type ParsedOfficeDocument, type ParseOfficeDocumentInput, } from "./office.js";
3
3
  export { detectSpreadsheetDocumentType, isSpreadsheetDocument, parseSpreadsheetDocument, type ParsedSpreadsheetDocument, type ParsedSpreadsheetSheet, type ParseSpreadsheetDocumentInput, type SpreadsheetDocumentType, } from "./spreadsheet.js";
4
- export { parsePptxPresentation, type ParsedPptxImage, type ParsedPptxElement, type ParsedPptxGrid, type ParsedPptxParagraph, type ParsedPptxPresentation, type ParsedPptxSlide, type ParsedPptxTextRun, } from "./pptx.js";
4
+ export { DEFAULT_PPTX_IMAGE_BYTE_LIMITS, PptxImageByteLimitError, parsePptxPresentation, type ParsedPptxImage, type ParsedPptxElement, type ParsedPptxGrid, type ParsedPptxParagraph, type ParsedPptxPresentation, type ParsedPptxSlide, type ParsedPptxTextRun, type PptxImageByteLimits, } from "./pptx.js";
5
5
  export { extractDocxSections, parseDocxDocument, sanitizeInertDocumentHtml, type ParsedDocxDocument, type ParsedDocxSection, } from "./docx.js";
6
6
  export { compositeFigmaColors, extractFigmaTopLevelFrames, figmaColorToHex, figmaContrastRatio, summarizeFigmaFrame, summarizeFigmaNode, type FigmaContextNode, type FigmaFrameSummary, type FigmaRgba, type SummarizeFigmaNodeResult, } from "./figma.js";
7
7
  export { cssBlendMode, gradientAngleDegreesFromHandles, gradientGeometryFromTransform, gradientRayAngleDegreesFromHandles, handlePositionsFromArrayTransform, handlePositionsFromObjectTransform, invert2x3, mat2x3FromArray, remapLinearStopPosition, resolveGradientHandles, vectorLength, type BlendModeResult, type BlendVerdict, type GradientGeometry, type GradientHandles, type GradientKind, type Mat2x3Array, type Mat2x3Object, type Vec2, } from "./figma-paint-math.js";
@@ -1,7 +1,7 @@
1
1
  export { acquireIngestionLease, assertInventoryComplete, consumeIngestionBudget, createIngestionBudgetState, createIngestionCheckpoint, ingestionBudgetStopReason, releaseIngestionLease, renewIngestionLease, } from "./orchestration.js";
2
2
  export { detectOfficeDocumentType, normalizeDocumentText, parseOfficeDocument, } from "./office.js";
3
3
  export { detectSpreadsheetDocumentType, isSpreadsheetDocument, parseSpreadsheetDocument, } from "./spreadsheet.js";
4
- export { parsePptxPresentation, } from "./pptx.js";
4
+ export { DEFAULT_PPTX_IMAGE_BYTE_LIMITS, PptxImageByteLimitError, parsePptxPresentation, } from "./pptx.js";
5
5
  export { extractDocxSections, parseDocxDocument, sanitizeInertDocumentHtml, } from "./docx.js";
6
6
  export { compositeFigmaColors, extractFigmaTopLevelFrames, figmaColorToHex, figmaContrastRatio, summarizeFigmaFrame, summarizeFigmaNode, } from "./figma.js";
7
7
  export { cssBlendMode, gradientAngleDegreesFromHandles, gradientGeometryFromTransform, gradientRayAngleDegreesFromHandles, handlePositionsFromArrayTransform, handlePositionsFromObjectTransform, invert2x3, mat2x3FromArray, remapLinearStopPosition, resolveGradientHandles, vectorLength, } from "./figma-paint-math.js";
@@ -155,7 +155,18 @@ export interface ParsedPptxPresentation {
155
155
  };
156
156
  hiddenSlideCount?: number;
157
157
  }
158
+ export interface PptxImageByteLimits {
159
+ maxImageBytes: number;
160
+ maxTotalImageBytes: number;
161
+ }
162
+ export declare const DEFAULT_PPTX_IMAGE_BYTE_LIMITS: Readonly<PptxImageByteLimits>;
163
+ export declare class PptxImageByteLimitError extends Error {
164
+ readonly limit: "per-image" | "aggregate";
165
+ readonly maxBytes: number;
166
+ constructor(limit: "per-image" | "aggregate", maxBytes: number);
167
+ }
158
168
  export declare function parsePptxPresentation(fileBuffer: Uint8Array, options?: {
159
169
  includeHiddenSlides?: boolean;
170
+ imageByteLimits?: Readonly<PptxImageByteLimits>;
160
171
  }): Promise<ParsedPptxPresentation>;
161
172
  export declare function parsePptxSlideMetadata(value: unknown): ParsedPptxSlideMetadata;
@@ -1,5 +1,34 @@
1
1
  import { loadOptionalPeer } from "../shared/optional-peer.js";
2
+ export const DEFAULT_PPTX_IMAGE_BYTE_LIMITS = Object.freeze({
3
+ maxImageBytes: 10 * 1024 * 1024,
4
+ maxTotalImageBytes: 50 * 1024 * 1024,
5
+ });
6
+ export class PptxImageByteLimitError extends Error {
7
+ limit;
8
+ maxBytes;
9
+ constructor(limit, maxBytes) {
10
+ super(`PPTX image data exceeded its ${limit} byte limit.`);
11
+ this.name = "PptxImageByteLimitError";
12
+ this.limit = limit;
13
+ this.maxBytes = maxBytes;
14
+ }
15
+ }
16
+ function resolvePptxImageByteLimits(limits) {
17
+ const configured = limits ?? DEFAULT_PPTX_IMAGE_BYTE_LIMITS;
18
+ if (!Number.isSafeInteger(configured.maxImageBytes) ||
19
+ configured.maxImageBytes < 0 ||
20
+ !Number.isSafeInteger(configured.maxTotalImageBytes) ||
21
+ configured.maxTotalImageBytes < 0) {
22
+ throw new RangeError("PPTX image byte limits must be non-negative integers.");
23
+ }
24
+ return {
25
+ maxImageBytes: configured.maxImageBytes,
26
+ maxTotalImageBytes: configured.maxTotalImageBytes,
27
+ };
28
+ }
2
29
  export async function parsePptxPresentation(fileBuffer, options = {}) {
30
+ const imageByteLimits = resolvePptxImageByteLimits(options.imageByteLimits);
31
+ const imageBudget = { totalBytes: 0, limits: imageByteLimits };
3
32
  const dependencies = await loadPptxDependencies();
4
33
  const loadZip = dependencies.loadZip.bind(dependencies);
5
34
  const parseXml = dependencies.parseXml.bind(dependencies);
@@ -127,6 +156,7 @@ export async function parsePptxPresentation(fileBuffer, options = {}) {
127
156
  themeCache,
128
157
  masterInfoCache,
129
158
  templateContextCache,
159
+ imageBudget,
130
160
  })) ?? fallbackContext;
131
161
  const number = slideNumber(slidePath);
132
162
  elements = await parseSlideElements({
@@ -143,6 +173,7 @@ export async function parsePptxPresentation(fileBuffer, options = {}) {
143
173
  placeholderDefaults: slideMasterContext.placeholderDefaults,
144
174
  slideNumber: slides.length + 1,
145
175
  tableStyles,
176
+ imageBudget,
146
177
  });
147
178
  images.unshift(...slideMasterContext.layerImages);
148
179
  elements.unshift(...substituteSlideNumber(slideMasterContext.layerElements, slides.length + 1));
@@ -372,6 +403,7 @@ async function buildSlideTemplateContext(args) {
372
403
  slideHeightEmu: args.slideHeightEmu,
373
404
  images: layerImages,
374
405
  colorContext,
406
+ imageBudget: args.imageBudget,
375
407
  })));
376
408
  }
377
409
  return {
@@ -410,6 +442,7 @@ async function parseTemplateLayerElements(args) {
410
442
  images,
411
443
  tablesDegraded,
412
444
  colorContext: args.colorContext,
445
+ imageBudget: args.imageBudget,
413
446
  context: { matrix: IDENTITY_MAT, rotation: 0 },
414
447
  })));
415
448
  }
@@ -562,6 +595,7 @@ async function parseSlideElements(args) {
562
595
  y: 0,
563
596
  width: args.slideWidthEmu ?? 0,
564
597
  height: args.slideHeightEmu ?? 0,
598
+ imageBudget: args.imageBudget,
565
599
  });
566
600
  if (image) {
567
601
  args.images.unshift(image.image);
@@ -671,6 +705,7 @@ async function parseShapeFragment(fragment, args) {
671
705
  width: transform.width,
672
706
  height: transform.height,
673
707
  crop: parseImageCrop(node),
708
+ imageBudget: args.imageBudget,
674
709
  });
675
710
  if (!image)
676
711
  return [];
@@ -1652,8 +1687,9 @@ async function loadPptxImage(args) {
1652
1687
  if (!imageFile)
1653
1688
  return null;
1654
1689
  const name = imagePath.split("/").at(-1) ?? "image";
1690
+ const imageData = await readPptxImageWithinBudget(imageFile, args.imageBudget);
1655
1691
  const image = {
1656
- data: new Uint8Array(await imageFile.async("nodebuffer")),
1692
+ data: new Uint8Array(imageData),
1657
1693
  mimeType: imageMimeType(name),
1658
1694
  name,
1659
1695
  aspectRatio: args.width && args.height ? args.width / args.height : undefined,
@@ -1679,6 +1715,50 @@ async function loadPptxImage(args) {
1679
1715
  },
1680
1716
  };
1681
1717
  }
1718
+ async function readPptxImageWithinBudget(imageFile, budget) {
1719
+ const stream = imageFile.nodeStream("nodebuffer");
1720
+ return await new Promise((resolve, reject) => {
1721
+ const chunks = [];
1722
+ let imageBytes = 0;
1723
+ let settled = false;
1724
+ const fail = (error) => {
1725
+ if (settled)
1726
+ return;
1727
+ settled = true;
1728
+ stream.destroy();
1729
+ reject(error);
1730
+ };
1731
+ stream.on("data", (chunk) => {
1732
+ if (settled)
1733
+ return;
1734
+ const nextImageBytes = imageBytes + chunk.byteLength;
1735
+ if (nextImageBytes > budget.limits.maxImageBytes) {
1736
+ fail(new PptxImageByteLimitError("per-image", budget.limits.maxImageBytes));
1737
+ return;
1738
+ }
1739
+ if (budget.totalBytes + nextImageBytes >
1740
+ budget.limits.maxTotalImageBytes) {
1741
+ fail(new PptxImageByteLimitError("aggregate", budget.limits.maxTotalImageBytes));
1742
+ return;
1743
+ }
1744
+ imageBytes = nextImageBytes;
1745
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
1746
+ });
1747
+ stream.on("error", (error) => {
1748
+ if (settled)
1749
+ return;
1750
+ settled = true;
1751
+ reject(error);
1752
+ });
1753
+ stream.on("end", () => {
1754
+ if (settled)
1755
+ return;
1756
+ settled = true;
1757
+ budget.totalBytes += imageBytes;
1758
+ resolve(Buffer.concat(chunks, imageBytes));
1759
+ });
1760
+ });
1761
+ }
1682
1762
  function flattenElementText(elements) {
1683
1763
  const output = [];
1684
1764
  const textElements = elements.filter((element) => element.kind === "text" && element.paragraphs);
@@ -44,6 +44,11 @@ export default defineAction({
44
44
  }
45
45
  },
46
46
  }),
47
+ mcpAnnotations: {
48
+ readOnlyHint: false,
49
+ destructiveHint: true,
50
+ openWorldHint: true,
51
+ },
47
52
  run: async ({ operation, platform, values }, ctx) => {
48
53
  switch (operation) {
49
54
  case "save-credentials":
@@ -9,6 +9,7 @@ import { backgroundRunCutOffReason, checkBackgroundAutomationCredentials, isBack
9
9
  import { nextOccurrence, isValidCron, describeCron, effectiveTimezone, } from "./cron.js";
10
10
  import { buildJobResourceContent, isRecoveredFactoryJob, jobBelongsToApp, parseJobResource, patchJobFrontmatterFields, recoveredFactoryOwnerOrgId, } from "./frontmatter.js";
11
11
  import { dispatchRemoteAutomation, finishRemoteAutomationHistory, getRemoteAutomationStatus, } from "./remote-execution.js";
12
+ import { automationRunOwnership } from "./run-history-ownership.js";
12
13
  import { automationRunClaimLeaseMs, claimAutomationRun, finishAutomationRun, getAutomationRun, listAutomationRuns, RUNS_RETAINED_PER_AUTOMATION, } from "./run-history.js";
13
14
  import { acquireAutomationSchedulerLease, recordAutomationSchedulerHealth, releaseAutomationSchedulerLease, renewAutomationSchedulerLease, AUTOMATION_SCHEDULER_LEASE_RENEWAL_MS, AutomationSchedulerLeaseLostError, } from "./scheduler-health.js";
14
15
  import { reapStaleWork } from "./stale-reaper.js";
@@ -273,7 +274,7 @@ async function processRecurringJobsWithLease(deps, leaseSignal, assertCanStart)
273
274
  meta.nextRun = nextOccurrence(meta.schedule, now, meta.timezone).toISOString();
274
275
  }
275
276
  if (await updateResource(resource, meta, body)) {
276
- await recoverStaleAutomationHistory(resource.owner, resource.path, now);
277
+ await recoverStaleAutomationHistory(staleHistoryOwner(resource, meta), resource.path, now);
277
278
  }
278
279
  continue;
279
280
  }
@@ -462,6 +463,21 @@ async function processRecurringJobsWithLease(deps, leaseSignal, assertCanStart)
462
463
  });
463
464
  }
464
465
  }
466
+ /**
467
+ * The owner the runner recorded this automation's history under: a legacy
468
+ * shared resource has no organization in its owner, so the resolved execution
469
+ * identity decides (the organization for an org-bound run, the creator
470
+ * otherwise). Recovery must query that owner, not the resource owner.
471
+ */
472
+ function staleHistoryOwner(resource, meta) {
473
+ const effectiveRunAs = meta.runAs ?? "creator";
474
+ const executionOwner = effectiveRunAs === "creator"
475
+ ? meta.createdBy?.trim() || resource.owner
476
+ : resource.owner;
477
+ return automationRunOwnership(resource.owner, executionOwner, recoveredFactoryOwnerOrgId(meta, resource.path, resource.owner) ??
478
+ meta.orgId ??
479
+ null).owner;
480
+ }
465
481
  async function recoverStaleAutomationHistory(owner, path, now) {
466
482
  const automation = path.replace(/^jobs\//, "").replace(/\.md$/, "");
467
483
  const nowMs = now.getTime();
@@ -10,6 +10,11 @@ export default defineAction({
10
10
  description: "Opt the current user into or out of one registered lab. Unset preferences inherit declared legacy flags or use the app-defined default; labs may expose new or unstable features.",
11
11
  schema,
12
12
  http: { method: "POST" },
13
+ mcpAnnotations: {
14
+ readOnlyHint: false,
15
+ destructiveHint: false,
16
+ openWorldHint: false,
17
+ },
13
18
  run: async (args, ctx) => {
14
19
  const email = ctx?.userEmail;
15
20
  if (!email)
@@ -20,6 +20,11 @@ export default defineAction({
20
20
  when: (_args, result) => normalizeActionChangeResult(result) !== null,
21
21
  projectResult: (_args, result) => normalizeActionChangeResult(result),
22
22
  },
23
+ mcpAnnotations: {
24
+ readOnlyHint: false,
25
+ destructiveHint: false,
26
+ openWorldHint: false,
27
+ },
23
28
  run: async (args, ctx) => {
24
29
  if (!ctx?.userEmail)
25
30
  throw new Error("Not authenticated.");
@@ -13,6 +13,11 @@ const schema = z.object({
13
13
  export default defineAction({
14
14
  description: "Save a human-proposed instruction update for an agent output. The draft is explicit and never applied automatically.",
15
15
  schema,
16
+ mcpAnnotations: {
17
+ readOnlyHint: false,
18
+ destructiveHint: false,
19
+ openWorldHint: false,
20
+ },
16
21
  authorize: authorizeObservabilityOrgAdmin,
17
22
  run: async (args, ctx) => {
18
23
  const { userId, orgId } = getObservabilityOrgAdminAccess(ctx);
@@ -95,6 +95,11 @@ function artifactEvidenceMatches(source, appId, artifactId) {
95
95
  }
96
96
  export default defineAction({
97
97
  description: "Persist a concise human-review summary for a run. Artifact IDs must exactly match IDs returned by get-observability-review-summary-source; do not create, guess, or infer IDs. Include only real design, slide-deck, or analytics artifacts.",
98
+ mcpAnnotations: {
99
+ readOnlyHint: false,
100
+ destructiveHint: true,
101
+ openWorldHint: false,
102
+ },
98
103
  schema: z
99
104
  .object({
100
105
  runId: z
@@ -2,6 +2,6 @@ export declare function createProgressHandler(): import("h3").EventHandlerWithFe
2
2
  error: string;
3
3
  ok?: undefined;
4
4
  } | {
5
- error?: undefined;
6
5
  ok: boolean;
6
+ error?: undefined;
7
7
  }>>;
@@ -75,7 +75,9 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
75
75
  user: "user";
76
76
  }>>;
77
77
  }, z.core.$strip>>, {
78
- message?: undefined;
78
+ id?: undefined;
79
+ deleted?: undefined;
80
+ provider?: undefined;
79
81
  found?: undefined;
80
82
  providers: {
81
83
  id: string;
@@ -87,47 +89,45 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
87
89
  updatedAt: number;
88
90
  }[];
89
91
  count: number;
90
- provider?: undefined;
91
- deleted?: undefined;
92
92
  registered?: undefined;
93
- id?: undefined;
94
93
  label?: undefined;
95
- } | {
96
94
  message?: undefined;
97
- providers?: undefined;
95
+ } | {
96
+ id?: undefined;
97
+ deleted?: undefined;
98
98
  count?: undefined;
99
+ providers?: undefined;
99
100
  found: boolean;
100
101
  provider: import("../custom-registry.js").CustomProviderConfig;
101
- deleted?: undefined;
102
102
  registered?: undefined;
103
- id?: undefined;
104
103
  label?: undefined;
105
- } | {
106
104
  message?: undefined;
107
- providers?: undefined;
108
- count?: undefined;
105
+ } | {
106
+ deleted?: undefined;
109
107
  provider?: undefined;
108
+ count?: undefined;
109
+ providers?: undefined;
110
110
  found: boolean;
111
111
  id: string;
112
- deleted?: undefined;
113
112
  registered?: undefined;
114
113
  label?: undefined;
115
- } | {
116
114
  message?: undefined;
115
+ } | {
116
+ provider?: undefined;
117
+ count?: undefined;
117
118
  found?: undefined;
118
119
  providers?: undefined;
119
- count?: undefined;
120
- provider?: undefined;
121
120
  deleted: boolean;
122
121
  id: string;
123
122
  registered?: undefined;
124
123
  label?: undefined;
124
+ message?: undefined;
125
125
  } | {
126
+ deleted?: undefined;
127
+ provider?: undefined;
128
+ count?: undefined;
126
129
  found?: undefined;
127
130
  providers?: undefined;
128
- count?: undefined;
129
- provider?: undefined;
130
- deleted?: undefined;
131
131
  registered: boolean;
132
132
  id: string;
133
133
  label: string;
@@ -317,8 +317,10 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
317
317
  scope?: "org" | "user" | undefined;
318
318
  }, {
319
319
  id?: undefined;
320
- found?: undefined;
320
+ provider?: undefined;
321
+ message?: undefined;
321
322
  deleted?: undefined;
323
+ found?: undefined;
322
324
  providers: {
323
325
  id: string;
324
326
  label: string;
@@ -329,46 +331,44 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
329
331
  updatedAt: number;
330
332
  }[];
331
333
  count: number;
332
- provider?: undefined;
333
334
  registered?: undefined;
334
335
  label?: undefined;
335
- message?: undefined;
336
336
  } | {
337
337
  id?: undefined;
338
+ count?: undefined;
339
+ message?: undefined;
338
340
  deleted?: undefined;
339
341
  providers?: undefined;
340
- count?: undefined;
341
342
  found: boolean;
342
343
  provider: import("../custom-registry.js").CustomProviderConfig;
343
344
  registered?: undefined;
344
345
  label?: undefined;
345
- message?: undefined;
346
346
  } | {
347
+ provider?: undefined;
348
+ count?: undefined;
349
+ message?: undefined;
347
350
  deleted?: undefined;
348
351
  providers?: undefined;
349
- count?: undefined;
350
- provider?: undefined;
351
352
  found: boolean;
352
353
  id: string;
353
354
  registered?: undefined;
354
355
  label?: undefined;
355
- message?: undefined;
356
356
  } | {
357
+ provider?: undefined;
358
+ count?: undefined;
359
+ message?: undefined;
357
360
  found?: undefined;
358
361
  providers?: undefined;
359
- count?: undefined;
360
- provider?: undefined;
361
362
  deleted: boolean;
362
363
  id: string;
363
364
  registered?: undefined;
364
365
  label?: undefined;
365
- message?: undefined;
366
366
  } | {
367
- found?: undefined;
367
+ provider?: undefined;
368
+ count?: undefined;
368
369
  deleted?: undefined;
370
+ found?: undefined;
369
371
  providers?: undefined;
370
- count?: undefined;
371
- provider?: undefined;
372
372
  registered: boolean;
373
373
  id: string;
374
374
  label: string;
@@ -73,6 +73,7 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
73
73
  offset?: unknown;
74
74
  limit?: unknown;
75
75
  }, {
76
+ deleted?: undefined;
76
77
  jobs: {
77
78
  id: string;
78
79
  name: string;
@@ -83,7 +84,6 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
83
84
  updatedAt: string;
84
85
  }[];
85
86
  total: number;
86
- deleted?: undefined;
87
87
  jobId?: undefined;
88
88
  } | {
89
89
  jobs?: undefined;
@@ -91,9 +91,9 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
91
91
  deleted: boolean;
92
92
  jobId: string;
93
93
  } | {
94
+ deleted?: undefined;
94
95
  jobs?: undefined;
95
96
  total?: undefined;
96
- deleted?: undefined;
97
97
  jobId?: undefined;
98
98
  hits: Record<string, unknown>[];
99
99
  offset: number;
@@ -787,7 +787,14 @@ const PROVIDER_CONFIGS = {
787
787
  docsUrls: ["https://developers.google.com/drive/api/reference/rest/v3"],
788
788
  specUrls: ["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"],
789
789
  allowedHostSuffixes: ["googleapis.com"],
790
- templateUses: ["brain", "content", "slides", "dispatch", "analytics"],
790
+ templateUses: [
791
+ "brain",
792
+ "content",
793
+ "slides",
794
+ "slides-2",
795
+ "dispatch",
796
+ "analytics",
797
+ ],
791
798
  examples: [
792
799
  { label: "List files", method: "GET", path: "/files" },
793
800
  { label: "Get file metadata", method: "GET", path: "/files/{fileId}" },
@@ -843,7 +850,7 @@ const PROVIDER_CONFIGS = {
843
850
  ],
844
851
  specUrls: ["https://slides.googleapis.com/$discovery/rest?version=v1"],
845
852
  allowedHostSuffixes: ["googleapis.com"],
846
- templateUses: ["brain", "content", "slides", "dispatch"],
853
+ templateUses: ["brain", "content", "slides", "slides-2", "dispatch"],
847
854
  examples: [
848
855
  {
849
856
  label: "Get presentation with slides and speaker notes",
@@ -10,6 +10,11 @@ const schema = z.object({
10
10
  export default defineAction({
11
11
  description: "Mark review feedback as consumed by the agent or reviewer workflow.",
12
12
  schema,
13
+ mcpAnnotations: {
14
+ readOnlyHint: false,
15
+ destructiveHint: false,
16
+ openWorldHint: false,
17
+ },
13
18
  run: async (args, ctx) => {
14
19
  const actionCtx = ctx;
15
20
  await assertReviewableResourceAccess(args.resourceType, args.resourceId, actionCtx, "editor");
@@ -40,6 +40,11 @@ const schema = z.object({
40
40
  export default defineAction({
41
41
  description: "Create an inline comment, annotation, or review thread for a resource. Body text supports inline Markdown without headings.",
42
42
  schema,
43
+ mcpAnnotations: {
44
+ readOnlyHint: false,
45
+ destructiveHint: false,
46
+ openWorldHint: true,
47
+ },
43
48
  run: async (args, ctx) => {
44
49
  const actionCtx = ctx;
45
50
  const access = await assertReviewableResourceAccess(args.resourceType, args.resourceId, actionCtx, "commenter");
@@ -12,6 +12,11 @@ const schema = z.object({
12
12
  export default defineAction({
13
13
  description: "Soft-delete a review comment.",
14
14
  schema,
15
+ mcpAnnotations: {
16
+ readOnlyHint: false,
17
+ destructiveHint: true,
18
+ openWorldHint: false,
19
+ },
15
20
  run: async (args, ctx) => {
16
21
  const actionCtx = ctx;
17
22
  const scope = {
@@ -11,6 +11,11 @@ export default defineAction({
11
11
  reaction: z.string().trim().min(1).max(32),
12
12
  active: z.boolean(),
13
13
  }),
14
+ mcpAnnotations: {
15
+ readOnlyHint: false,
16
+ destructiveHint: false,
17
+ openWorldHint: false,
18
+ },
14
19
  run: async (args, ctx) => {
15
20
  await assertReviewableResourceAccess(args.resourceType, args.resourceId, ctx, "commenter");
16
21
  const comment = await getReviewCommentById(args.commentId, {
@@ -29,6 +29,11 @@ const schema = z.object({
29
29
  export default defineAction({
30
30
  description: "Reply to an existing review comment thread with inline Markdown text without headings.",
31
31
  schema,
32
+ mcpAnnotations: {
33
+ readOnlyHint: false,
34
+ destructiveHint: false,
35
+ openWorldHint: true,
36
+ },
32
37
  run: async (args, ctx) => {
33
38
  const actionCtx = ctx;
34
39
  const scope = {
@@ -21,6 +21,11 @@ const schema = z
21
21
  export default defineAction({
22
22
  description: "Resolve or reopen an inline comment or review thread. Resolution notes support inline Markdown without headings and are only valid when resolving.",
23
23
  schema,
24
+ mcpAnnotations: {
25
+ readOnlyHint: false,
26
+ destructiveHint: true,
27
+ openWorldHint: false,
28
+ },
24
29
  run: async (args, ctx) => {
25
30
  const status = args.status ?? "resolved";
26
31
  const actionCtx = ctx;
@@ -10,6 +10,11 @@ const schema = z.object({
10
10
  export default defineAction({
11
11
  description: "Send one open review thread to the agent queue without routing other threads.",
12
12
  schema,
13
+ mcpAnnotations: {
14
+ readOnlyHint: false,
15
+ destructiveHint: false,
16
+ openWorldHint: false,
17
+ },
13
18
  run: async (args, ctx) => {
14
19
  const actionCtx = ctx;
15
20
  const access = await assertReviewableResourceAccess(args.resourceType, args.resourceId, actionCtx, "editor");
@@ -12,6 +12,11 @@ const schema = z.object({
12
12
  export default defineAction({
13
13
  description: "Set the review status for a reusable resource.",
14
14
  schema,
15
+ mcpAnnotations: {
16
+ readOnlyHint: false,
17
+ destructiveHint: true,
18
+ openWorldHint: false,
19
+ },
15
20
  run: async (args, ctx) => {
16
21
  const actionCtx = ctx;
17
22
  const access = await assertReviewableResourceAccess(args.resourceType, args.resourceId, actionCtx, "editor");