@agent-native/core 0.58.0 → 0.58.2

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 (42) hide show
  1. package/dist/agent/production-agent.d.ts.map +1 -1
  2. package/dist/agent/production-agent.js +26 -12
  3. package/dist/agent/production-agent.js.map +1 -1
  4. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  5. package/dist/agent/thread-data-builder.js +10 -2
  6. package/dist/agent/thread-data-builder.js.map +1 -1
  7. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  8. package/dist/client/agent-chat-adapter.js +29 -5
  9. package/dist/client/agent-chat-adapter.js.map +1 -1
  10. package/dist/client/chat/attachment-adapters.d.ts.map +1 -1
  11. package/dist/client/chat/attachment-adapters.js +29 -4
  12. package/dist/client/chat/attachment-adapters.js.map +1 -1
  13. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  14. package/dist/client/composer/PromptComposer.js +5 -1
  15. package/dist/client/composer/PromptComposer.js.map +1 -1
  16. package/dist/client/composer/attachment-accept.d.ts +2 -0
  17. package/dist/client/composer/attachment-accept.d.ts.map +1 -1
  18. package/dist/client/composer/attachment-accept.js +30 -1
  19. package/dist/client/composer/attachment-accept.js.map +1 -1
  20. package/dist/data-widgets/index.d.ts +5 -5
  21. package/dist/file-upload/pre-upload-attachments.d.ts +2 -0
  22. package/dist/file-upload/pre-upload-attachments.d.ts.map +1 -1
  23. package/dist/file-upload/pre-upload-attachments.js +66 -9
  24. package/dist/file-upload/pre-upload-attachments.js.map +1 -1
  25. package/dist/server/agent-chat-plugin.d.ts +16 -0
  26. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  27. package/dist/server/agent-chat-plugin.js +67 -5
  28. package/dist/server/agent-chat-plugin.js.map +1 -1
  29. package/dist/server/auth.d.ts.map +1 -1
  30. package/dist/server/auth.js +20 -0
  31. package/dist/server/auth.js.map +1 -1
  32. package/dist/server/prompts/framework-core-compact.d.ts.map +1 -1
  33. package/dist/server/prompts/framework-core-compact.js +2 -1
  34. package/dist/server/prompts/framework-core-compact.js.map +1 -1
  35. package/dist/server/prompts/framework-core.d.ts.map +1 -1
  36. package/dist/server/prompts/framework-core.js +1 -0
  37. package/dist/server/prompts/framework-core.js.map +1 -1
  38. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +1 -1
  39. package/docs/content/authentication.md +14 -12
  40. package/docs/content/native-chat-ui.md +12 -0
  41. package/package.json +1 -1
  42. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"attachment-adapters.d.ts","sourceRoot":"","sources":["../../../src/client/chat/attachment-adapters.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EAElB,MAAM,qBAAqB,CAAC;AAI7B,eAAO,MAAM,aAAa,QAAkB,CAAC;AAM7C,eAAO,MAAM,eAAe,QAAkB,CAAC;AAC/C,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAGxC,eAAO,MAAM,wBAAwB,QAAoB,CAAC;AAE1D,eAAO,MAAM,8BAA8B,OAAO,CAAC;AACnD,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAW3C,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAI3D;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAOjE;AAmBD;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,IAAI,EACV,IAAI,GAAE;IACJ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,GACL,OAAO,CAAC,MAAM,CAAC,CA0BjB;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAkCrE;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAItE;AAED,MAAM,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;AAElD,qBAAa,iCAAkC,YAAW,iBAAiB;IAClE,MAAM,SAAa;IAEb,GAAG,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAWtD,IAAI,CACf,UAAU,EAAE,iBAAiB,GAC5B,OAAO,CAAC,kBAAkB,CAAC;IAajB,MAAM;CAGpB;AAED,qBAAa,+BAAgC,YAAW,iBAAiB;IAChE,MAAM,SAA0B;IAE1B,GAAG,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAWtD,IAAI,CACf,UAAU,EAAE,iBAAiB,GAC5B,OAAO,CAAC,kBAAkB,CAAC;IAsBjB,MAAM;CAGpB;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGnE;AAED,wBAAgB,6BAA6B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAKzE;AAED,wBAAgB,2BAA2B,CACzC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,GACzB,gBAAgB,EAAE,GAAG,SAAS,CAiBhC;AAMD,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAIlD;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG3E;AAED,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,gBAAgB,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAmB5C;AAED,wBAAsB,0BAA0B,CAC9C,WAAW,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,GACnC,OAAO,CAAC,gBAAgB,EAAE,GAAG,SAAS,CAAC,CA0EzC"}
1
+ {"version":3,"file":"attachment-adapters.d.ts","sourceRoot":"","sources":["../../../src/client/chat/attachment-adapters.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EAElB,MAAM,qBAAqB,CAAC;AAQ7B,eAAO,MAAM,aAAa,QAAkB,CAAC;AAM7C,eAAO,MAAM,eAAe,QAAkB,CAAC;AAC/C,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAGxC,eAAO,MAAM,wBAAwB,QAAoB,CAAC;AAE1D,eAAO,MAAM,8BAA8B,OAAO,CAAC;AACnD,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAW3C,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAK3D;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAOjE;AAmBD;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,IAAI,EACV,IAAI,GAAE;IACJ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,GACL,OAAO,CAAC,MAAM,CAAC,CA0BjB;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAkCrE;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAItE;AAED,MAAM,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;AAElD,qBAAa,iCAAkC,YAAW,iBAAiB;IAClE,MAAM,SAA2B;IAE3B,GAAG,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAWtD,IAAI,CACf,UAAU,EAAE,iBAAiB,GAC5B,OAAO,CAAC,kBAAkB,CAAC;IAajB,MAAM;CAGpB;AAED,qBAAa,+BAAgC,YAAW,iBAAiB;IAChE,MAAM,SAAmC;IAEnC,GAAG,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAWtD,IAAI,CACf,UAAU,EAAE,iBAAiB,GAC5B,OAAO,CAAC,kBAAkB,CAAC;IAsBjB,MAAM;CAGpB;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGnE;AAED,wBAAgB,6BAA6B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAKzE;AAED,wBAAgB,2BAA2B,CACzC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,GACzB,gBAAgB,EAAE,GAAG,SAAS,CAiBhC;AAMD,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAMlD;AAOD,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG3E;AAED,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,gBAAgB,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAmB5C;AAED,wBAAsB,0BAA0B,CAC9C,WAAW,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,GACnC,OAAO,CAAC,gBAAgB,EAAE,GAAG,SAAS,CAAC,CA2FzC"}
@@ -1,4 +1,5 @@
1
1
  // Owns: image/document/text attachment adapters and attachment serialization helpers.
2
+ import { CHAT_DOCUMENT_ATTACHMENT_ACCEPT, IMAGE_ATTACHMENT_ACCEPT, } from "../composer/attachment-accept.js";
2
3
  // Maximum PDF/document size (4 MB). Larger PDFs would bloat the JSON POST
3
4
  // body past Vercel's ~4.5 MB limit after base64 encoding (+33% overhead).
4
5
  export const MAX_PDF_BYTES = 4 * 1024 * 1024;
@@ -27,6 +28,8 @@ export function inferDocumentContentType(file) {
27
28
  return file.type;
28
29
  if (file.name.toLowerCase().endsWith(".pdf"))
29
30
  return "application/pdf";
31
+ if (file.name.toLowerCase().endsWith(".svg"))
32
+ return "image/svg+xml";
30
33
  return "application/octet-stream";
31
34
  }
32
35
  export function getFileDataURL(file) {
@@ -130,7 +133,7 @@ export function estimateAttachmentBodyBytes(dataUrls) {
130
133
  return dataUrls.reduce((sum, url) => sum + url.length, 0) * 1.15;
131
134
  }
132
135
  export class DownscalingImageAttachmentAdapter {
133
- accept = "image/*";
136
+ accept = IMAGE_ATTACHMENT_ACCEPT;
134
137
  async add(state) {
135
138
  return {
136
139
  id: crypto.randomUUID(),
@@ -158,7 +161,7 @@ export class DownscalingImageAttachmentAdapter {
158
161
  }
159
162
  }
160
163
  export class BinaryDocumentAttachmentAdapter {
161
- accept = "application/pdf,.pdf";
164
+ accept = CHAT_DOCUMENT_ATTACHMENT_ACCEPT;
162
165
  async add(state) {
163
166
  return {
164
167
  id: state.file.name,
@@ -231,7 +234,11 @@ export function isTextLikeFile(file) {
231
234
  return true;
232
235
  if (file.type === "application/json")
233
236
  return true;
234
- return /\.(txt|md|markdown|csv|json|yaml|yml)$/i.test(file.name);
237
+ return /\.(txt|md|markdown|csv|json|yaml|yml|html?|css|xml)$/i.test(file.name);
238
+ }
239
+ function isSvgFile(file) {
240
+ const contentType = file.type.split(";")[0]?.trim().toLowerCase();
241
+ return contentType === "image/svg+xml" || /\.svg$/i.test(file.name);
235
242
  }
236
243
  export function textFileAttachmentEnvelope(file, text) {
237
244
  const contentType = file.type || "text/plain";
@@ -282,7 +289,25 @@ export async function serializeQueuedAttachments(attachments) {
282
289
  }
283
290
  if (typeof File !== "undefined" && attachment.file instanceof File) {
284
291
  const file = attachment.file;
285
- if (file.type.startsWith("image/")) {
292
+ if (isSvgFile(file)) {
293
+ const contentType = inferDocumentContentType(file);
294
+ queued.push({
295
+ id,
296
+ type: "document",
297
+ name,
298
+ contentType,
299
+ status: { type: "complete" },
300
+ content: [
301
+ {
302
+ type: "file",
303
+ filename: file.name,
304
+ data: await getFileDataURL(file),
305
+ mimeType: contentType,
306
+ },
307
+ ],
308
+ });
309
+ }
310
+ else if (file.type.startsWith("image/")) {
286
311
  queued.push({
287
312
  id,
288
313
  type: "image",
@@ -1 +1 @@
1
- {"version":3,"file":"attachment-adapters.js","sourceRoot":"","sources":["../../../src/client/chat/attachment-adapters.ts"],"names":[],"mappings":"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","sourcesContent":["// Owns: image/document/text attachment adapters and attachment serialization helpers.\n\nimport type {\n AttachmentAdapter,\n CompleteAttachment,\n PendingAttachment,\n Attachment,\n} from \"@assistant-ui/react\";\n\n// Maximum PDF/document size (4 MB). Larger PDFs would bloat the JSON POST\n// body past Vercel's ~4.5 MB limit after base64 encoding (+33% overhead).\nexport const MAX_PDF_BYTES = 4 * 1024 * 1024;\n\n// Anthropic / OpenAI vision inputs choke on multi-megabyte images, and\n// base64-encoding a raw screenshot eats enough heap to crash the composer\n// (PayloadTooLarge / \"Maximum call stack\" in serializers). Downscale large\n// images on the client before we ever serialize them.\nexport const MAX_IMAGE_BYTES = 4 * 1024 * 1024;\nexport const MAX_IMAGE_DIMENSION = 2048;\n// Estimated total serialized body budget (JSON POST). Vercel/Netlify cap ~4.5 MB.\n// We stop well below to leave room for the text payload and JSON framing.\nexport const MAX_ESTIMATED_BODY_BYTES = 3.5 * 1024 * 1024;\n// At 3.5 MB of serializable attachments, aggressively re-downscale images.\nexport const AGGRESSIVE_MAX_IMAGE_DIMENSION = 1024;\nexport const AGGRESSIVE_JPEG_QUALITY = 0.7;\n\n/** MIME types that vision models accept natively (no canvas transcoding needed). */\nconst WEB_SAFE_IMAGE_TYPES = new Set([\n \"image/jpeg\",\n \"image/jpg\",\n \"image/png\",\n \"image/gif\",\n \"image/webp\",\n]);\n\nexport function inferDocumentContentType(file: File): string {\n if (file.type) return file.type;\n if (file.name.toLowerCase().endsWith(\".pdf\")) return \"application/pdf\";\n return \"application/octet-stream\";\n}\n\nexport function getFileDataURL(file: File | Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = (error) => reject(error);\n reader.readAsDataURL(file);\n });\n}\n\nfunction loadImage(url: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = () => reject(new Error(\"Failed to decode pasted image\"));\n img.src = url;\n });\n}\n\n/**\n * Returns true when the MIME type is natively accepted by vision APIs\n * (jpeg / png / gif / webp). HEIC, TIFF, AVIF, BMP, etc. return false.\n */\nfunction isWebSafeImageType(mimeType: string): boolean {\n return WEB_SAFE_IMAGE_TYPES.has(mimeType.toLowerCase());\n}\n\n/**\n * Transcode an image to a web-safe JPEG or PNG via canvas and return its\n * data-URL. Throws if canvas is unavailable.\n */\nexport async function transcodeImageToDataURL(\n file: File,\n opts: {\n maxDimension?: number;\n jpegQuality?: number;\n } = {},\n): Promise<string> {\n const maxDimension = opts.maxDimension ?? MAX_IMAGE_DIMENSION;\n const jpegQuality = opts.jpegQuality ?? 0.85;\n\n const objectUrl = URL.createObjectURL(file);\n try {\n const img = await loadImage(objectUrl);\n const ratio = Math.min(\n maxDimension / img.naturalWidth,\n maxDimension / img.naturalHeight,\n 1,\n );\n const width = Math.max(1, Math.round(img.naturalWidth * ratio));\n const height = Math.max(1, Math.round(img.naturalHeight * ratio));\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) throw new Error(\"Canvas 2D context unavailable\");\n ctx.drawImage(img, 0, 0, width, height);\n const keepPng =\n file.type === \"image/png\" && file.size <= MAX_IMAGE_BYTES * 2;\n return canvas.toDataURL(keepPng ? \"image/png\" : \"image/jpeg\", jpegQuality);\n } finally {\n URL.revokeObjectURL(objectUrl);\n }\n}\n\n/**\n * Return a web-safe, size-bounded data-URL for an image file.\n *\n * - Always transcodes formats that vision APIs reject (HEIC, TIFF, AVIF, BMP, …)\n * to JPEG/PNG via canvas, regardless of file size.\n * - Also downscales files over MAX_IMAGE_BYTES so large screenshots/photos\n * don't blow up the request body.\n * - Throws (does NOT silently fall back) when the format is non-web-safe and\n * canvas transcoding fails — the adapter should surface a visible error.\n */\nexport async function getImageFileDataURL(file: File): Promise<string> {\n const needsTranscode = !isWebSafeImageType(file.type);\n const tooBig = file.size > MAX_IMAGE_BYTES;\n\n if (!needsTranscode && !tooBig) {\n // Already a supported type and within size budget — serve raw.\n return getFileDataURL(file);\n }\n\n if (typeof document === \"undefined\" || typeof Image === \"undefined\") {\n if (needsTranscode) {\n // Can't transcode server-side — surface an error rather than silently\n // attaching garbage bytes that the model cannot decode.\n throw new Error(\n `\"${file.name}\" is a ${file.type || \"unknown\"} image. Only JPEG, PNG, GIF, and WebP are supported in this environment.`,\n );\n }\n // Can't downscale but the type is fine — send raw and hope for the best.\n return getFileDataURL(file);\n }\n\n // Transcode via canvas. Throws on decode failure for non-web-safe types\n // so the adapter can surface a visible error; falls back to raw for\n // oversized-but-supported types (the older behaviour).\n try {\n return await transcodeImageToDataURL(file);\n } catch (err) {\n if (needsTranscode) {\n // Re-throw so the DownscalingImageAttachmentAdapter.send() can surface it.\n throw err;\n }\n // Safe type, just couldn't downscale — fall back to the raw file.\n return getFileDataURL(file);\n }\n}\n\n/**\n * Estimate the serialized byte cost of a collection of attachment data-URLs\n * (base64 strings, accounting for JSON string escaping overhead).\n */\nexport function estimateAttachmentBodyBytes(dataUrls: string[]): number {\n // JSON.stringify adds ~2 bytes of quotes per string; base64 is already\n // accounted for in the string length. Add 15% for JSON framing.\n return dataUrls.reduce((sum, url) => sum + url.length, 0) * 1.15;\n}\n\nexport type QueuedAttachment = CompleteAttachment;\n\nexport class DownscalingImageAttachmentAdapter implements AttachmentAdapter {\n public accept = \"image/*\";\n\n public async add(state: { file: File }): Promise<PendingAttachment> {\n return {\n id: crypto.randomUUID(),\n type: \"image\",\n name: state.file.name,\n contentType: state.file.type,\n file: state.file,\n status: { type: \"requires-action\", reason: \"composer-send\" },\n };\n }\n\n public async send(\n attachment: PendingAttachment,\n ): Promise<CompleteAttachment> {\n return {\n ...attachment,\n status: { type: \"complete\" },\n content: [\n {\n type: \"image\",\n image: await getImageFileDataURL(attachment.file),\n },\n ],\n };\n }\n\n public async remove() {\n // noop\n }\n}\n\nexport class BinaryDocumentAttachmentAdapter implements AttachmentAdapter {\n public accept = \"application/pdf,.pdf\";\n\n public async add(state: { file: File }): Promise<PendingAttachment> {\n return {\n id: state.file.name,\n type: \"document\",\n name: state.file.name,\n contentType: inferDocumentContentType(state.file),\n file: state.file,\n status: { type: \"requires-action\", reason: \"composer-send\" },\n };\n }\n\n public async send(\n attachment: PendingAttachment,\n ): Promise<CompleteAttachment> {\n if (attachment.file && attachment.file.size > MAX_PDF_BYTES) {\n const mb = (attachment.file.size / 1024 / 1024).toFixed(1);\n const maxMb = (MAX_PDF_BYTES / 1024 / 1024).toFixed(0);\n throw new Error(\n `\"${attachment.name}\" is ${mb} MB — PDFs are capped at ${maxMb} MB to stay within message limits. Please reduce the file size or split it into smaller parts.`,\n );\n }\n return {\n ...attachment,\n status: { type: \"complete\" },\n content: [\n {\n type: \"file\",\n filename: attachment.name,\n data: await getFileDataURL(attachment.file),\n mimeType: inferDocumentContentType(attachment.file),\n },\n ],\n };\n }\n\n public async remove() {\n // noop\n }\n}\n\nexport function imageContentTypeFromDataUrl(dataUrl: string): string {\n const match = /^data:([^;,]+)/.exec(dataUrl);\n return match?.[1] || \"image/jpeg\";\n}\n\nexport function imageExtensionFromContentType(contentType: string): string {\n if (contentType === \"image/png\") return \"png\";\n if (contentType === \"image/webp\") return \"webp\";\n if (contentType === \"image/gif\") return \"gif\";\n return \"jpg\";\n}\n\nexport function createAgentImageAttachments(\n images?: readonly string[],\n): QueuedAttachment[] | undefined {\n const validImages = (images ?? []).filter((image) => image.trim().length > 0);\n if (validImages.length === 0) return undefined;\n\n return validImages.map((image, index) => {\n const contentType = imageContentTypeFromDataUrl(image);\n const extension = imageExtensionFromContentType(contentType);\n const name = `image-${index + 1}.${extension}`;\n return {\n id: `agent-chat-image-${index + 1}`,\n type: \"image\",\n name,\n contentType,\n status: { type: \"complete\" },\n content: [{ type: \"image\", image }],\n };\n });\n}\n\nfunction escapeQueuedAttachmentAttribute(value: string): string {\n return value.replace(/&/g, \"&amp;\").replace(/\"/g, \"&quot;\");\n}\n\nexport function isTextLikeFile(file: File): boolean {\n if (file.type.startsWith(\"text/\")) return true;\n if (file.type === \"application/json\") return true;\n return /\\.(txt|md|markdown|csv|json|yaml|yml)$/i.test(file.name);\n}\n\nexport function textFileAttachmentEnvelope(file: File, text: string): string {\n const contentType = file.type || \"text/plain\";\n return `<attachment name=\"${escapeQueuedAttachmentAttribute(file.name)}\" contentType=\"${escapeQueuedAttachmentAttribute(contentType)}\">\\n${text}\\n</attachment>`;\n}\n\nexport function serializeAttachmentContentPart(\n part: Record<string, unknown>,\n): QueuedAttachment[\"content\"][number] | null {\n if (part.type === \"image\" && typeof part.image === \"string\") {\n return { type: \"image\", image: part.image };\n }\n if (part.type === \"text\" && typeof part.text === \"string\") {\n return { type: \"text\", text: part.text };\n }\n if (part.type === \"file\" && typeof part.data === \"string\") {\n return {\n type: \"file\",\n data: part.data,\n mimeType:\n typeof part.mimeType === \"string\"\n ? part.mimeType\n : \"application/octet-stream\",\n ...(typeof part.filename === \"string\" ? { filename: part.filename } : {}),\n };\n }\n return null;\n}\n\nexport async function serializeQueuedAttachments(\n attachments?: ReadonlyArray<unknown>,\n): Promise<QueuedAttachment[] | undefined> {\n const queued: QueuedAttachment[] = [];\n for (const raw of attachments ?? []) {\n const attachment = raw as Partial<Attachment> & { file?: File };\n const name = attachment.name || attachment.file?.name || \"attachment\";\n const id = attachment.id || name;\n const type = attachment.type || \"file\";\n const contentType = attachment.contentType || attachment.file?.type;\n\n if (Array.isArray(attachment.content) && attachment.content.length > 0) {\n const content = attachment.content\n .map((part) =>\n serializeAttachmentContentPart(part as Record<string, unknown>),\n )\n .filter((part): part is QueuedAttachment[\"content\"][number] => !!part);\n if (content.length > 0) {\n queued.push({\n id,\n type,\n name,\n contentType,\n status: { type: \"complete\" },\n content,\n });\n }\n continue;\n }\n\n if (typeof File !== \"undefined\" && attachment.file instanceof File) {\n const file = attachment.file;\n if (file.type.startsWith(\"image/\")) {\n queued.push({\n id,\n type: \"image\",\n name,\n contentType: file.type,\n status: { type: \"complete\" },\n content: [{ type: \"image\", image: await getImageFileDataURL(file) }],\n });\n } else if (isTextLikeFile(file)) {\n queued.push({\n id,\n type: \"file\",\n name,\n contentType: file.type || \"text/plain\",\n status: { type: \"complete\" },\n content: [\n {\n type: \"text\",\n text: textFileAttachmentEnvelope(file, await file.text()),\n },\n ],\n });\n } else {\n queued.push({\n id,\n type: \"document\",\n name,\n contentType: inferDocumentContentType(file),\n status: { type: \"complete\" },\n content: [\n {\n type: \"file\",\n filename: file.name,\n data: await getFileDataURL(file),\n mimeType: inferDocumentContentType(file),\n },\n ],\n });\n }\n }\n }\n\n return queued.length > 0 ? queued : undefined;\n}\n"]}
1
+ {"version":3,"file":"attachment-adapters.js","sourceRoot":"","sources":["../../../src/client/chat/attachment-adapters.ts"],"names":[],"mappings":"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","sourcesContent":["// Owns: image/document/text attachment adapters and attachment serialization helpers.\n\nimport type {\n AttachmentAdapter,\n CompleteAttachment,\n PendingAttachment,\n Attachment,\n} from \"@assistant-ui/react\";\nimport {\n CHAT_DOCUMENT_ATTACHMENT_ACCEPT,\n IMAGE_ATTACHMENT_ACCEPT,\n} from \"../composer/attachment-accept.js\";\n\n// Maximum PDF/document size (4 MB). Larger PDFs would bloat the JSON POST\n// body past Vercel's ~4.5 MB limit after base64 encoding (+33% overhead).\nexport const MAX_PDF_BYTES = 4 * 1024 * 1024;\n\n// Anthropic / OpenAI vision inputs choke on multi-megabyte images, and\n// base64-encoding a raw screenshot eats enough heap to crash the composer\n// (PayloadTooLarge / \"Maximum call stack\" in serializers). Downscale large\n// images on the client before we ever serialize them.\nexport const MAX_IMAGE_BYTES = 4 * 1024 * 1024;\nexport const MAX_IMAGE_DIMENSION = 2048;\n// Estimated total serialized body budget (JSON POST). Vercel/Netlify cap ~4.5 MB.\n// We stop well below to leave room for the text payload and JSON framing.\nexport const MAX_ESTIMATED_BODY_BYTES = 3.5 * 1024 * 1024;\n// At 3.5 MB of serializable attachments, aggressively re-downscale images.\nexport const AGGRESSIVE_MAX_IMAGE_DIMENSION = 1024;\nexport const AGGRESSIVE_JPEG_QUALITY = 0.7;\n\n/** MIME types that vision models accept natively (no canvas transcoding needed). */\nconst WEB_SAFE_IMAGE_TYPES = new Set([\n \"image/jpeg\",\n \"image/jpg\",\n \"image/png\",\n \"image/gif\",\n \"image/webp\",\n]);\n\nexport function inferDocumentContentType(file: File): string {\n if (file.type) return file.type;\n if (file.name.toLowerCase().endsWith(\".pdf\")) return \"application/pdf\";\n if (file.name.toLowerCase().endsWith(\".svg\")) return \"image/svg+xml\";\n return \"application/octet-stream\";\n}\n\nexport function getFileDataURL(file: File | Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = (error) => reject(error);\n reader.readAsDataURL(file);\n });\n}\n\nfunction loadImage(url: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = () => reject(new Error(\"Failed to decode pasted image\"));\n img.src = url;\n });\n}\n\n/**\n * Returns true when the MIME type is natively accepted by vision APIs\n * (jpeg / png / gif / webp). HEIC, TIFF, AVIF, BMP, etc. return false.\n */\nfunction isWebSafeImageType(mimeType: string): boolean {\n return WEB_SAFE_IMAGE_TYPES.has(mimeType.toLowerCase());\n}\n\n/**\n * Transcode an image to a web-safe JPEG or PNG via canvas and return its\n * data-URL. Throws if canvas is unavailable.\n */\nexport async function transcodeImageToDataURL(\n file: File,\n opts: {\n maxDimension?: number;\n jpegQuality?: number;\n } = {},\n): Promise<string> {\n const maxDimension = opts.maxDimension ?? MAX_IMAGE_DIMENSION;\n const jpegQuality = opts.jpegQuality ?? 0.85;\n\n const objectUrl = URL.createObjectURL(file);\n try {\n const img = await loadImage(objectUrl);\n const ratio = Math.min(\n maxDimension / img.naturalWidth,\n maxDimension / img.naturalHeight,\n 1,\n );\n const width = Math.max(1, Math.round(img.naturalWidth * ratio));\n const height = Math.max(1, Math.round(img.naturalHeight * ratio));\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) throw new Error(\"Canvas 2D context unavailable\");\n ctx.drawImage(img, 0, 0, width, height);\n const keepPng =\n file.type === \"image/png\" && file.size <= MAX_IMAGE_BYTES * 2;\n return canvas.toDataURL(keepPng ? \"image/png\" : \"image/jpeg\", jpegQuality);\n } finally {\n URL.revokeObjectURL(objectUrl);\n }\n}\n\n/**\n * Return a web-safe, size-bounded data-URL for an image file.\n *\n * - Always transcodes formats that vision APIs reject (HEIC, TIFF, AVIF, BMP, …)\n * to JPEG/PNG via canvas, regardless of file size.\n * - Also downscales files over MAX_IMAGE_BYTES so large screenshots/photos\n * don't blow up the request body.\n * - Throws (does NOT silently fall back) when the format is non-web-safe and\n * canvas transcoding fails — the adapter should surface a visible error.\n */\nexport async function getImageFileDataURL(file: File): Promise<string> {\n const needsTranscode = !isWebSafeImageType(file.type);\n const tooBig = file.size > MAX_IMAGE_BYTES;\n\n if (!needsTranscode && !tooBig) {\n // Already a supported type and within size budget — serve raw.\n return getFileDataURL(file);\n }\n\n if (typeof document === \"undefined\" || typeof Image === \"undefined\") {\n if (needsTranscode) {\n // Can't transcode server-side — surface an error rather than silently\n // attaching garbage bytes that the model cannot decode.\n throw new Error(\n `\"${file.name}\" is a ${file.type || \"unknown\"} image. Only JPEG, PNG, GIF, and WebP are supported in this environment.`,\n );\n }\n // Can't downscale but the type is fine — send raw and hope for the best.\n return getFileDataURL(file);\n }\n\n // Transcode via canvas. Throws on decode failure for non-web-safe types\n // so the adapter can surface a visible error; falls back to raw for\n // oversized-but-supported types (the older behaviour).\n try {\n return await transcodeImageToDataURL(file);\n } catch (err) {\n if (needsTranscode) {\n // Re-throw so the DownscalingImageAttachmentAdapter.send() can surface it.\n throw err;\n }\n // Safe type, just couldn't downscale — fall back to the raw file.\n return getFileDataURL(file);\n }\n}\n\n/**\n * Estimate the serialized byte cost of a collection of attachment data-URLs\n * (base64 strings, accounting for JSON string escaping overhead).\n */\nexport function estimateAttachmentBodyBytes(dataUrls: string[]): number {\n // JSON.stringify adds ~2 bytes of quotes per string; base64 is already\n // accounted for in the string length. Add 15% for JSON framing.\n return dataUrls.reduce((sum, url) => sum + url.length, 0) * 1.15;\n}\n\nexport type QueuedAttachment = CompleteAttachment;\n\nexport class DownscalingImageAttachmentAdapter implements AttachmentAdapter {\n public accept = IMAGE_ATTACHMENT_ACCEPT;\n\n public async add(state: { file: File }): Promise<PendingAttachment> {\n return {\n id: crypto.randomUUID(),\n type: \"image\",\n name: state.file.name,\n contentType: state.file.type,\n file: state.file,\n status: { type: \"requires-action\", reason: \"composer-send\" },\n };\n }\n\n public async send(\n attachment: PendingAttachment,\n ): Promise<CompleteAttachment> {\n return {\n ...attachment,\n status: { type: \"complete\" },\n content: [\n {\n type: \"image\",\n image: await getImageFileDataURL(attachment.file),\n },\n ],\n };\n }\n\n public async remove() {\n // noop\n }\n}\n\nexport class BinaryDocumentAttachmentAdapter implements AttachmentAdapter {\n public accept = CHAT_DOCUMENT_ATTACHMENT_ACCEPT;\n\n public async add(state: { file: File }): Promise<PendingAttachment> {\n return {\n id: state.file.name,\n type: \"document\",\n name: state.file.name,\n contentType: inferDocumentContentType(state.file),\n file: state.file,\n status: { type: \"requires-action\", reason: \"composer-send\" },\n };\n }\n\n public async send(\n attachment: PendingAttachment,\n ): Promise<CompleteAttachment> {\n if (attachment.file && attachment.file.size > MAX_PDF_BYTES) {\n const mb = (attachment.file.size / 1024 / 1024).toFixed(1);\n const maxMb = (MAX_PDF_BYTES / 1024 / 1024).toFixed(0);\n throw new Error(\n `\"${attachment.name}\" is ${mb} MB — PDFs are capped at ${maxMb} MB to stay within message limits. Please reduce the file size or split it into smaller parts.`,\n );\n }\n return {\n ...attachment,\n status: { type: \"complete\" },\n content: [\n {\n type: \"file\",\n filename: attachment.name,\n data: await getFileDataURL(attachment.file),\n mimeType: inferDocumentContentType(attachment.file),\n },\n ],\n };\n }\n\n public async remove() {\n // noop\n }\n}\n\nexport function imageContentTypeFromDataUrl(dataUrl: string): string {\n const match = /^data:([^;,]+)/.exec(dataUrl);\n return match?.[1] || \"image/jpeg\";\n}\n\nexport function imageExtensionFromContentType(contentType: string): string {\n if (contentType === \"image/png\") return \"png\";\n if (contentType === \"image/webp\") return \"webp\";\n if (contentType === \"image/gif\") return \"gif\";\n return \"jpg\";\n}\n\nexport function createAgentImageAttachments(\n images?: readonly string[],\n): QueuedAttachment[] | undefined {\n const validImages = (images ?? []).filter((image) => image.trim().length > 0);\n if (validImages.length === 0) return undefined;\n\n return validImages.map((image, index) => {\n const contentType = imageContentTypeFromDataUrl(image);\n const extension = imageExtensionFromContentType(contentType);\n const name = `image-${index + 1}.${extension}`;\n return {\n id: `agent-chat-image-${index + 1}`,\n type: \"image\",\n name,\n contentType,\n status: { type: \"complete\" },\n content: [{ type: \"image\", image }],\n };\n });\n}\n\nfunction escapeQueuedAttachmentAttribute(value: string): string {\n return value.replace(/&/g, \"&amp;\").replace(/\"/g, \"&quot;\");\n}\n\nexport function isTextLikeFile(file: File): boolean {\n if (file.type.startsWith(\"text/\")) return true;\n if (file.type === \"application/json\") return true;\n return /\\.(txt|md|markdown|csv|json|yaml|yml|html?|css|xml)$/i.test(\n file.name,\n );\n}\n\nfunction isSvgFile(file: File): boolean {\n const contentType = file.type.split(\";\")[0]?.trim().toLowerCase();\n return contentType === \"image/svg+xml\" || /\\.svg$/i.test(file.name);\n}\n\nexport function textFileAttachmentEnvelope(file: File, text: string): string {\n const contentType = file.type || \"text/plain\";\n return `<attachment name=\"${escapeQueuedAttachmentAttribute(file.name)}\" contentType=\"${escapeQueuedAttachmentAttribute(contentType)}\">\\n${text}\\n</attachment>`;\n}\n\nexport function serializeAttachmentContentPart(\n part: Record<string, unknown>,\n): QueuedAttachment[\"content\"][number] | null {\n if (part.type === \"image\" && typeof part.image === \"string\") {\n return { type: \"image\", image: part.image };\n }\n if (part.type === \"text\" && typeof part.text === \"string\") {\n return { type: \"text\", text: part.text };\n }\n if (part.type === \"file\" && typeof part.data === \"string\") {\n return {\n type: \"file\",\n data: part.data,\n mimeType:\n typeof part.mimeType === \"string\"\n ? part.mimeType\n : \"application/octet-stream\",\n ...(typeof part.filename === \"string\" ? { filename: part.filename } : {}),\n };\n }\n return null;\n}\n\nexport async function serializeQueuedAttachments(\n attachments?: ReadonlyArray<unknown>,\n): Promise<QueuedAttachment[] | undefined> {\n const queued: QueuedAttachment[] = [];\n for (const raw of attachments ?? []) {\n const attachment = raw as Partial<Attachment> & { file?: File };\n const name = attachment.name || attachment.file?.name || \"attachment\";\n const id = attachment.id || name;\n const type = attachment.type || \"file\";\n const contentType = attachment.contentType || attachment.file?.type;\n\n if (Array.isArray(attachment.content) && attachment.content.length > 0) {\n const content = attachment.content\n .map((part) =>\n serializeAttachmentContentPart(part as Record<string, unknown>),\n )\n .filter((part): part is QueuedAttachment[\"content\"][number] => !!part);\n if (content.length > 0) {\n queued.push({\n id,\n type,\n name,\n contentType,\n status: { type: \"complete\" },\n content,\n });\n }\n continue;\n }\n\n if (typeof File !== \"undefined\" && attachment.file instanceof File) {\n const file = attachment.file;\n if (isSvgFile(file)) {\n const contentType = inferDocumentContentType(file);\n queued.push({\n id,\n type: \"document\",\n name,\n contentType,\n status: { type: \"complete\" },\n content: [\n {\n type: \"file\",\n filename: file.name,\n data: await getFileDataURL(file),\n mimeType: contentType,\n },\n ],\n });\n } else if (file.type.startsWith(\"image/\")) {\n queued.push({\n id,\n type: \"image\",\n name,\n contentType: file.type,\n status: { type: \"complete\" },\n content: [{ type: \"image\", image: await getImageFileDataURL(file) }],\n });\n } else if (isTextLikeFile(file)) {\n queued.push({\n id,\n type: \"file\",\n name,\n contentType: file.type || \"text/plain\",\n status: { type: \"complete\" },\n content: [\n {\n type: \"text\",\n text: textFileAttachmentEnvelope(file, await file.text()),\n },\n ],\n });\n } else {\n queued.push({\n id,\n type: \"document\",\n name,\n contentType: inferDocumentContentType(file),\n status: { type: \"complete\" },\n content: [\n {\n type: \"file\",\n filename: file.name,\n data: await getFileDataURL(file),\n mimeType: inferDocumentContentType(file),\n },\n ],\n });\n }\n }\n }\n\n return queued.length > 0 ? queued : undefined;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"PromptComposer.d.ts","sourceRoot":"","sources":["../../../src/client/composer/PromptComposer.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PromptComposer.d.ts","sourceRoot":"","sources":["../../../src/client/composer/PromptComposer.tsx"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@ import { IconX } from "@tabler/icons-react";
6
6
  import { cn } from "../utils.js";
7
7
  import { AgentComposerFrame } from "./AgentComposerFrame.js";
8
8
  import { DEFAULT_VOICE_DICTATION_ENABLED, TiptapComposer, } from "./TiptapComposer.js";
9
+ import { IMAGE_ATTACHMENT_ACCEPT } from "./attachment-accept.js";
9
10
  import { useChatModels } from "../use-chat-models.js";
10
11
  import { TooltipProvider } from "../components/ui/tooltip.js";
11
12
  import { AssistantUiStaleIndexErrorBoundary } from "../assistant-ui-recovery.js";
@@ -50,6 +51,9 @@ class BinaryDocumentAttachmentAdapter {
50
51
  /* noop */
51
52
  }
52
53
  }
54
+ class RasterImageAttachmentAdapter extends SimpleImageAttachmentAdapter {
55
+ accept = IMAGE_ATTACHMENT_ACCEPT;
56
+ }
53
57
  function isInlineableTextFile(file) {
54
58
  if (file.type.startsWith("text/"))
55
59
  return true;
@@ -240,7 +244,7 @@ function PromptComposerInner({ onSubmit, placeholder, disabled, autoFocus, class
240
244
  */
241
245
  export function PromptComposer(props) {
242
246
  const attachmentAdapter = useMemo(() => new CompositeAttachmentAdapter([
243
- new SimpleImageAttachmentAdapter(),
247
+ new RasterImageAttachmentAdapter(),
244
248
  new BinaryDocumentAttachmentAdapter(),
245
249
  new TextAttachmentAdapter(),
246
250
  ]), []);
@@ -1 +1 @@
1
- {"version":3,"file":"PromptComposer.js","sourceRoot":"","sources":["../../../src/client/composer/PromptComposer.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type Ref,\n type ReactNode,\n} from \"react\";\nimport {\n AssistantRuntimeProvider,\n ThreadPrimitive,\n useAui,\n useComposer,\n useLocalRuntime,\n} from \"@assistant-ui/react\";\nimport type {\n Attachment,\n AttachmentAdapter,\n ChatModelAdapter,\n CompleteAttachment,\n PendingAttachment,\n} from \"@assistant-ui/react\";\nimport {\n CompositeAttachmentAdapter,\n SimpleImageAttachmentAdapter,\n} from \"@assistant-ui/react\";\nimport { IconX } from \"@tabler/icons-react\";\nimport { cn } from \"../utils.js\";\nimport { AgentComposerFrame } from \"./AgentComposerFrame.js\";\nimport {\n DEFAULT_VOICE_DICTATION_ENABLED,\n TiptapComposer,\n type ComposerSubmitIntent,\n type TiptapComposerHandle,\n type TiptapComposerSubmitOptions,\n} from \"./TiptapComposer.js\";\nimport type {\n AgentComposerLayoutVariant,\n Reference,\n SkillResult,\n SlashCommand,\n} from \"./types.js\";\nimport { useChatModels, type EngineModelGroup } from \"../use-chat-models.js\";\nimport { TooltipProvider } from \"../components/ui/tooltip.js\";\nimport { AssistantUiStaleIndexErrorBoundary } from \"../assistant-ui-recovery.js\";\nimport type { ReasoningEffort } from \"../../shared/reasoning-effort.js\";\nimport { isPastedTextAttachmentName } from \"./pasted-text.js\";\nimport { PastedTextChip } from \"./PastedTextChip.js\";\nimport {\n PROMPT_DOCUMENT_ATTACHMENT_ACCEPT,\n TextAttachmentAdapter,\n} from \"./attachment-accept.js\";\nimport { escapePromptAttachmentAttribute } from \"./prompt-attachments.js\";\n\nconst MAX_INLINE_TEXT_FILE_CHARS = 60_000;\n\n/**\n * Files the user attached via the \"+\" button in PromptComposer. The host owns\n * what to do with them — typically POST to a per-app upload endpoint and pass\n * the resulting URLs/paths into the prompt that gets sent to the agent.\n */\nexport type PromptComposerFile = File;\n\nexport interface PromptComposerSubmitOptions {\n intent?: ComposerSubmitIntent;\n model?: string;\n engine?: string;\n effort?: ReasoningEffort;\n}\n\nexport interface PromptComposerProps {\n /** Called when the user submits the composer. */\n onSubmit: (\n text: string,\n files: PromptComposerFile[],\n references: Reference[],\n options: PromptComposerSubmitOptions,\n ) => void;\n placeholder?: string;\n disabled?: boolean;\n autoFocus?: boolean;\n className?: string;\n style?: CSSProperties;\n rootClassName?: string;\n rootStyle?: CSSProperties;\n /** Forwarded to TiptapComposer for draft persistence. */\n draftScope?: string;\n /** Keep the submitted prompt in the editor. Default: false. */\n preserveDraftOnSubmit?: boolean;\n /** Show the model selector (default: true). */\n showModelSelector?: boolean;\n /** Show the voice dictation button. Defaults to DEFAULT_VOICE_DICTATION_ENABLED. */\n voiceEnabled?: boolean;\n /** Show file upload controls and pass submitted files to onSubmit (default: true). */\n attachmentsEnabled?: boolean;\n /**\n * Controls the shared \"+\" affordance. Defaults to upload-only for standalone\n * prompt forms; chat surfaces can opt into the full sidebar menu.\n */\n plusMenuMode?: \"full\" | \"upload-only\" | \"hidden\";\n /** Programmatically seed the composer with plain text. */\n initialText?: string;\n /** Stable key used to re-apply `initialText` when the host picks a preset. */\n initialTextKey?: string | number;\n /** Optional host-owned control rendered directly after the \"+\" button. */\n modeControl?: ReactNode;\n /** Explicit host-owned toolbar slot rendered directly after the \"+\" button. */\n toolbarSlot?: ReactNode;\n /** Custom attachment button to render instead of the default \"+\" affordance. */\n attachButton?: ReactNode;\n /** Custom action button to render instead of the default send button. */\n actionButton?: ReactNode;\n /** Extra button rendered alongside the default send button. */\n extraActionButton?: ReactNode;\n /** Shared sizing/layout variant for host surfaces. Default keeps sidebar behavior. */\n layoutVariant?: AgentComposerLayoutVariant;\n /** Additional slash commands surfaced in the shared / menu. */\n slashCommands?: SlashCommand[];\n /** Additional slash skills surfaced in the shared / menu. */\n slashSkills?: SkillResult[];\n /** Include built-in sidebar slash commands like /clear and /help. Default true. */\n includeDefaultSlashCommands?: boolean;\n /** Include app-discovered skills from the default agent endpoint. Default true. */\n includeDefaultSlashSkills?: boolean;\n /** Called when a slash command from the shared / menu is executed. */\n onSlashCommand?: (command: string) => void;\n /** External model list for hosts that already resolve models outside the app. */\n availableModels?: EngineModelGroup[];\n selectedModel?: string;\n selectedEngine?: string;\n selectedEffort?: ReasoningEffort;\n onModelChange?: (model: string, engine: string) => void;\n onEffortChange?: (effort: ReasoningEffort) => void;\n /**\n * Enable server-backed model/provider status checks. Defaults off when the\n * host supplies model state and callbacks, otherwise on.\n */\n modelStatusChecksEnabled?: boolean;\n /** Called whenever the plain editor text changes. */\n onTextChange?: (text: string) => void;\n /**\n * Override the Builder.io connect action in the model picker. When provided,\n * clicking \"Connect Builder.io\" calls this instead of opening a browser popup.\n * Used by the Electron desktop app to route through the native IPC handler.\n */\n onConnectProvider?: () => void;\n /** Imperative handle for focusing the composer. */\n composerRef?: Ref<TiptapComposerHandle>;\n}\n\n// Minimal pass-through adapter. PromptComposer always submits through\n// onSubmitOverride, so the runtime never actually calls this — but\n// `useLocalRuntime` needs *something* shaped like a ChatModelAdapter.\nconst NOOP_ADAPTER: ChatModelAdapter = {\n async *run() {\n return;\n },\n};\n\n/**\n * Local binary document adapter so reference PDFs, decks, and docs can be\n * attached without dragging the whole assistant chat module into bundles that\n * just want a prompt popover.\n */\nclass BinaryDocumentAttachmentAdapter implements AttachmentAdapter {\n public accept = PROMPT_DOCUMENT_ATTACHMENT_ACCEPT;\n\n public async add(state: { file: File }): Promise<PendingAttachment> {\n return {\n id: state.file.name,\n type: \"document\",\n name: state.file.name,\n contentType: state.file.type || \"application/octet-stream\",\n file: state.file,\n status: { type: \"requires-action\", reason: \"composer-send\" },\n };\n }\n\n public async send(\n attachment: PendingAttachment,\n ): Promise<CompleteAttachment> {\n return {\n ...attachment,\n status: { type: \"complete\" },\n content: [],\n };\n }\n\n public async remove() {\n /* noop */\n }\n}\n\nfunction isInlineableTextFile(file: File): boolean {\n if (file.type.startsWith(\"text/\")) return true;\n if (file.type === \"application/json\") return true;\n return /\\.(txt|md|markdown|csv|json|yaml|yml|html?|css|xml)$/i.test(\n file.name,\n );\n}\n\nfunction formatInlineTextFile(name: string, text: string): string {\n const truncated = text.length > MAX_INLINE_TEXT_FILE_CHARS;\n const body = truncated ? text.slice(0, MAX_INLINE_TEXT_FILE_CHARS) : text;\n return [\n `<uploaded-text-file name=\"${escapePromptAttachmentAttribute(name)}\">`,\n body,\n truncated\n ? `[Truncated after ${MAX_INLINE_TEXT_FILE_CHARS} characters.]`\n : \"\",\n \"</uploaded-text-file>\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n}\n\nexport async function buildPromptComposerSubmission(options: {\n text: string;\n attachments?: ReadonlyArray<unknown>;\n}): Promise<{ text: string; files: File[] }> {\n const files: File[] = [];\n const pastedTextBlocks: string[] = [];\n const rawText = options.text;\n\n for (const att of options.attachments ?? []) {\n const a = att as Attachment;\n if (\"file\" in a && a.file instanceof File) {\n const file = a.file;\n if (isPastedTextAttachmentName(file.name)) {\n try {\n pastedTextBlocks.push(await file.text());\n } catch {\n files.push(file);\n }\n } else {\n if (isInlineableTextFile(file)) {\n try {\n pastedTextBlocks.push(\n formatInlineTextFile(file.name, await file.text()),\n );\n } catch {\n // Keep the upload path fallback below.\n }\n }\n // Note: images are NOT inlined into the prompt text even when small.\n // Inlining a base64 data-URL into a text string consumes an enormous\n // number of tokens (≈ 700 K per MB) and most hosts handle images via\n // proper attachment channels. The `files` array below carries the image\n // for the host to process through a dedicated attachment pipeline.\n files.push(file);\n }\n }\n }\n\n return {\n text: pastedTextBlocks.length\n ? [rawText.trim(), ...pastedTextBlocks].filter(Boolean).join(\"\\n\\n\")\n : rawText,\n files,\n };\n}\n\nfunction getImageSrc(attachment: Attachment): string | null {\n if (attachment.type !== \"image\") return null;\n if (\"file\" in attachment && attachment.file) {\n return URL.createObjectURL(attachment.file);\n }\n const imagePart = attachment.content?.find((part) => part.type === \"image\");\n return imagePart && \"image\" in imagePart ? imagePart.image : null;\n}\n\nfunction ImagePreviewLightbox({\n src,\n alt,\n onClose,\n}: {\n src: string;\n alt: string;\n onClose: () => void;\n}) {\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", handler);\n document.body.style.overflow = \"hidden\";\n return () => {\n document.removeEventListener(\"keydown\", handler);\n document.body.style.overflow = \"\";\n };\n }, [onClose]);\n\n return (\n <div\n role=\"dialog\"\n aria-label=\"Image preview\"\n onClick={onClose}\n className=\"fixed inset-0 z-[300] flex items-center justify-center bg-black/80 p-6 cursor-zoom-out\"\n >\n <img\n src={src}\n alt={alt}\n onClick={(e) => e.stopPropagation()}\n className=\"max-h-full max-w-full object-contain rounded-md shadow-2xl cursor-default\"\n />\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Close preview\"\n className=\"absolute right-4 top-4 flex h-8 w-8 cursor-pointer items-center justify-center rounded-full border border-white/30 bg-black/40 text-white hover:bg-black/60\"\n >\n <IconX className=\"h-4 w-4\" />\n </button>\n </div>\n );\n}\n\nfunction AttachmentChip({\n attachment,\n onRemove,\n}: {\n attachment: Attachment;\n onRemove: (id: string) => void;\n}) {\n const src = useMemo(() => getImageSrc(attachment), [attachment]);\n const [previewOpen, setPreviewOpen] = useState(false);\n useEffect(\n () => () => {\n if (src?.startsWith(\"blob:\")) URL.revokeObjectURL(src);\n },\n [src],\n );\n\n if (isPastedTextAttachmentName(attachment.name)) {\n return <PastedTextChip attachment={attachment} onRemove={onRemove} />;\n }\n\n if (src) {\n return (\n <>\n <button\n type=\"button\"\n onClick={() => setPreviewOpen(true)}\n aria-label={`Preview ${attachment.name}`}\n className=\"agent-composer-attachment-image group relative flex h-16 min-w-16 max-w-28 cursor-zoom-in items-center justify-center overflow-hidden rounded-lg border border-border/70 bg-muted/50\"\n >\n <img\n src={src}\n alt={attachment.name}\n className=\"max-h-full max-w-full object-contain p-1\"\n />\n <span\n role=\"button\"\n tabIndex={0}\n onClick={(e) => {\n e.stopPropagation();\n onRemove(attachment.id);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n e.stopPropagation();\n onRemove(attachment.id);\n }\n }}\n aria-label={`Remove ${attachment.name}`}\n className=\"absolute right-1 top-1 flex h-5 w-5 cursor-pointer items-center justify-center rounded-full border border-border/60 bg-background/90 text-muted-foreground hover:text-foreground\"\n >\n <IconX className=\"h-3 w-3\" />\n </span>\n </button>\n {previewOpen ? (\n <ImagePreviewLightbox\n src={src}\n alt={attachment.name}\n onClose={() => setPreviewOpen(false)}\n />\n ) : null}\n </>\n );\n }\n\n return (\n <div className=\"agent-composer-attachment-chip group relative inline-flex max-w-[200px] items-center gap-2 rounded-md border border-border/70 bg-muted/50 px-2 py-1.5 text-xs\">\n <div className=\"flex h-6 w-6 shrink-0 items-center justify-center rounded bg-background text-[9px] font-semibold uppercase text-muted-foreground\">\n {attachment.name.split(\".\").pop() || \"file\"}\n </div>\n <span className=\"min-w-0 truncate font-medium\">{attachment.name}</span>\n <button\n type=\"button\"\n onClick={() => onRemove(attachment.id)}\n aria-label={`Remove ${attachment.name}`}\n className=\"flex h-5 w-5 shrink-0 cursor-pointer items-center justify-center rounded text-muted-foreground hover:text-foreground\"\n >\n <IconX className=\"h-3 w-3\" />\n </button>\n </div>\n );\n}\n\nfunction PromptAttachmentStrip() {\n const attachments = useComposer((state) => state.attachments);\n const aui = useAui();\n\n const handleRemove = useCallback(\n (id: string) => {\n void aui.composer().attachment({ id }).remove();\n },\n [aui],\n );\n\n if (attachments.length === 0) return null;\n return (\n <div className=\"agent-composer-attachment-strip flex flex-wrap gap-2 px-2 pt-2\">\n {attachments.map((attachment) => (\n <AttachmentChip\n key={attachment.id}\n attachment={attachment}\n onRemove={handleRemove}\n />\n ))}\n </div>\n );\n}\n\nfunction PromptComposerInner({\n onSubmit,\n placeholder,\n disabled,\n autoFocus,\n className,\n style,\n rootClassName,\n rootStyle,\n draftScope,\n preserveDraftOnSubmit = false,\n showModelSelector = true,\n voiceEnabled = DEFAULT_VOICE_DICTATION_ENABLED,\n attachmentsEnabled = true,\n plusMenuMode,\n initialText,\n initialTextKey,\n modeControl,\n toolbarSlot,\n attachButton,\n actionButton,\n extraActionButton,\n layoutVariant,\n slashCommands,\n slashSkills,\n includeDefaultSlashCommands,\n includeDefaultSlashSkills,\n onSlashCommand,\n availableModels,\n selectedModel,\n selectedEngine,\n selectedEffort,\n onModelChange,\n onEffortChange,\n modelStatusChecksEnabled,\n onTextChange,\n onConnectProvider,\n composerRef,\n}: PromptComposerProps) {\n const localRef = useRef<TiptapComposerHandle>(null);\n const handleRef = composerRef ?? localRef;\n const hostManagedModels = Boolean(\n availableModels && selectedModel && onModelChange,\n );\n const resolvedModelStatusChecksEnabled =\n modelStatusChecksEnabled ?? !hostManagedModels;\n const models = useChatModels({\n enabled: showModelSelector && resolvedModelStatusChecksEnabled,\n });\n const composerModel = showModelSelector\n ? (selectedModel ?? models.selectedModel)\n : undefined;\n const composerEngine = showModelSelector\n ? (selectedEngine ?? models.selectedEngine)\n : undefined;\n const composerEffort = showModelSelector\n ? (selectedEffort ?? models.selectedEffort)\n : undefined;\n const composerModelGroups = showModelSelector\n ? (availableModels ?? models.availableModels)\n : undefined;\n const handleModelChange = showModelSelector\n ? (onModelChange ?? models.onModelChange)\n : undefined;\n const handleEffortChange = showModelSelector\n ? (onEffortChange ?? models.onEffortChange)\n : undefined;\n\n useEffect(() => {\n if (!autoFocus) return;\n const id = window.setTimeout(() => {\n const target =\n typeof handleRef === \"object\" && handleRef && \"current\" in handleRef\n ? handleRef.current\n : null;\n target?.focus();\n }, 50);\n return () => window.clearTimeout(id);\n }, [autoFocus, handleRef]);\n\n const handleSubmit = useCallback(\n async (\n text: string,\n references: Reference[],\n attachments?: ReadonlyArray<unknown>,\n submitOptions?: TiptapComposerSubmitOptions,\n ) => {\n // PromptComposer hosts (NewWorkspaceAppFlow, create-extension, create-deck,\n // …) submit a single string prompt — they don't run the assistant-ui\n // attachment send pipeline. TiptapComposer auto-converts large pastes\n // into a \"Pasted text\" chip, which would otherwise disappear into an\n // unprocessed File. Inline the chip body back into the prompt text so\n // newlines and full content survive the round-trip.\n const { text: finalText, files } = await buildPromptComposerSubmission({\n text,\n attachments,\n });\n onSubmit(finalText, files, references, {\n intent: submitOptions?.intent ?? \"immediate\",\n model: composerModel,\n engine: composerEngine,\n effort: composerEffort,\n });\n },\n [composerEffort, composerEngine, composerModel, onSubmit],\n );\n\n return (\n <AgentComposerFrame\n className={cn(\"text-left\", className)}\n rootClassName={rootClassName}\n style={style}\n rootStyle={rootStyle}\n layoutVariant={layoutVariant}\n >\n <PromptAttachmentStrip />\n <TiptapComposer\n focusRef={handleRef}\n disabled={disabled}\n placeholder={placeholder}\n initialText={initialText}\n initialTextKey={initialTextKey}\n onSubmit={handleSubmit}\n clearOnSubmit={!preserveDraftOnSubmit}\n plusMenuMode={\n plusMenuMode ?? (attachmentsEnabled ? \"upload-only\" : \"hidden\")\n }\n attachButton={attachButton}\n modeControl={modeControl}\n toolbarSlot={toolbarSlot}\n actionButton={actionButton}\n extraActionButton={extraActionButton}\n layoutVariant={layoutVariant}\n slashCommands={slashCommands}\n slashSkills={slashSkills}\n includeDefaultSlashCommands={includeDefaultSlashCommands}\n includeDefaultSlashSkills={includeDefaultSlashSkills}\n onSlashCommand={onSlashCommand}\n voiceEnabled={voiceEnabled}\n onTextChange={onTextChange}\n draftScope={draftScope}\n selectedModel={composerModel}\n selectedEffort={composerEffort}\n availableModels={composerModelGroups}\n onModelChange={handleModelChange}\n onEffortChange={handleEffortChange}\n providerConnectStatusEnabled={resolvedModelStatusChecksEnabled}\n onConnectProvider={onConnectProvider}\n />\n </AgentComposerFrame>\n );\n}\n\n/**\n * Standalone composer that mirrors the agent sidebar's input experience —\n * voice dictation, file upload, model selector, submit-on-Enter — for use in\n * popovers and inline prompt forms (create tool, create deck, create dashboard,\n * the Dispatch new-app flow, etc.).\n *\n * The host owns submission: when the user presses Enter or clicks submit,\n * `onSubmit(text, files, references, options)` is called. PromptComposer runs\n * its own minimal assistant-ui runtime so it can be dropped into any subtree\n * without needing the outer chat to be mounted.\n */\nexport function PromptComposer(props: PromptComposerProps) {\n const attachmentAdapter = useMemo(\n () =>\n new CompositeAttachmentAdapter([\n new SimpleImageAttachmentAdapter(),\n new BinaryDocumentAttachmentAdapter(),\n new TextAttachmentAdapter(),\n ]),\n [],\n );\n const runtime = useLocalRuntime(NOOP_ADAPTER, {\n adapters: { attachments: attachmentAdapter },\n });\n const resetKey = [\n props.draftScope ?? \"\",\n props.initialTextKey ?? \"\",\n props.initialText ?? \"\",\n ].join(\":\");\n\n return (\n <TooltipProvider delayDuration={200}>\n <AssistantRuntimeProvider runtime={runtime}>\n <ThreadPrimitive.Root\n className=\"contents\"\n style={{ display: \"contents\" }}\n >\n <AssistantUiStaleIndexErrorBoundary\n resetKey={resetKey}\n componentName=\"PromptComposer\"\n >\n <PromptComposerInner {...props} />\n </AssistantUiStaleIndexErrorBoundary>\n </ThreadPrimitive.Root>\n </AssistantRuntimeProvider>\n </TooltipProvider>\n );\n}\n"]}
1
+ {"version":3,"file":"PromptComposer.js","sourceRoot":"","sources":["../../../src/client/composer/PromptComposer.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type Ref,\n type ReactNode,\n} from \"react\";\nimport {\n AssistantRuntimeProvider,\n ThreadPrimitive,\n useAui,\n useComposer,\n useLocalRuntime,\n} from \"@assistant-ui/react\";\nimport type {\n Attachment,\n AttachmentAdapter,\n ChatModelAdapter,\n CompleteAttachment,\n PendingAttachment,\n} from \"@assistant-ui/react\";\nimport {\n CompositeAttachmentAdapter,\n SimpleImageAttachmentAdapter,\n} from \"@assistant-ui/react\";\nimport { IconX } from \"@tabler/icons-react\";\nimport { cn } from \"../utils.js\";\nimport { AgentComposerFrame } from \"./AgentComposerFrame.js\";\nimport {\n DEFAULT_VOICE_DICTATION_ENABLED,\n TiptapComposer,\n type ComposerSubmitIntent,\n type TiptapComposerHandle,\n type TiptapComposerSubmitOptions,\n} from \"./TiptapComposer.js\";\nimport { IMAGE_ATTACHMENT_ACCEPT } from \"./attachment-accept.js\";\nimport type {\n AgentComposerLayoutVariant,\n Reference,\n SkillResult,\n SlashCommand,\n} from \"./types.js\";\nimport { useChatModels, type EngineModelGroup } from \"../use-chat-models.js\";\nimport { TooltipProvider } from \"../components/ui/tooltip.js\";\nimport { AssistantUiStaleIndexErrorBoundary } from \"../assistant-ui-recovery.js\";\nimport type { ReasoningEffort } from \"../../shared/reasoning-effort.js\";\nimport { isPastedTextAttachmentName } from \"./pasted-text.js\";\nimport { PastedTextChip } from \"./PastedTextChip.js\";\nimport {\n PROMPT_DOCUMENT_ATTACHMENT_ACCEPT,\n TextAttachmentAdapter,\n} from \"./attachment-accept.js\";\nimport { escapePromptAttachmentAttribute } from \"./prompt-attachments.js\";\n\nconst MAX_INLINE_TEXT_FILE_CHARS = 60_000;\n\n/**\n * Files the user attached via the \"+\" button in PromptComposer. The host owns\n * what to do with them — typically POST to a per-app upload endpoint and pass\n * the resulting URLs/paths into the prompt that gets sent to the agent.\n */\nexport type PromptComposerFile = File;\n\nexport interface PromptComposerSubmitOptions {\n intent?: ComposerSubmitIntent;\n model?: string;\n engine?: string;\n effort?: ReasoningEffort;\n}\n\nexport interface PromptComposerProps {\n /** Called when the user submits the composer. */\n onSubmit: (\n text: string,\n files: PromptComposerFile[],\n references: Reference[],\n options: PromptComposerSubmitOptions,\n ) => void;\n placeholder?: string;\n disabled?: boolean;\n autoFocus?: boolean;\n className?: string;\n style?: CSSProperties;\n rootClassName?: string;\n rootStyle?: CSSProperties;\n /** Forwarded to TiptapComposer for draft persistence. */\n draftScope?: string;\n /** Keep the submitted prompt in the editor. Default: false. */\n preserveDraftOnSubmit?: boolean;\n /** Show the model selector (default: true). */\n showModelSelector?: boolean;\n /** Show the voice dictation button. Defaults to DEFAULT_VOICE_DICTATION_ENABLED. */\n voiceEnabled?: boolean;\n /** Show file upload controls and pass submitted files to onSubmit (default: true). */\n attachmentsEnabled?: boolean;\n /**\n * Controls the shared \"+\" affordance. Defaults to upload-only for standalone\n * prompt forms; chat surfaces can opt into the full sidebar menu.\n */\n plusMenuMode?: \"full\" | \"upload-only\" | \"hidden\";\n /** Programmatically seed the composer with plain text. */\n initialText?: string;\n /** Stable key used to re-apply `initialText` when the host picks a preset. */\n initialTextKey?: string | number;\n /** Optional host-owned control rendered directly after the \"+\" button. */\n modeControl?: ReactNode;\n /** Explicit host-owned toolbar slot rendered directly after the \"+\" button. */\n toolbarSlot?: ReactNode;\n /** Custom attachment button to render instead of the default \"+\" affordance. */\n attachButton?: ReactNode;\n /** Custom action button to render instead of the default send button. */\n actionButton?: ReactNode;\n /** Extra button rendered alongside the default send button. */\n extraActionButton?: ReactNode;\n /** Shared sizing/layout variant for host surfaces. Default keeps sidebar behavior. */\n layoutVariant?: AgentComposerLayoutVariant;\n /** Additional slash commands surfaced in the shared / menu. */\n slashCommands?: SlashCommand[];\n /** Additional slash skills surfaced in the shared / menu. */\n slashSkills?: SkillResult[];\n /** Include built-in sidebar slash commands like /clear and /help. Default true. */\n includeDefaultSlashCommands?: boolean;\n /** Include app-discovered skills from the default agent endpoint. Default true. */\n includeDefaultSlashSkills?: boolean;\n /** Called when a slash command from the shared / menu is executed. */\n onSlashCommand?: (command: string) => void;\n /** External model list for hosts that already resolve models outside the app. */\n availableModels?: EngineModelGroup[];\n selectedModel?: string;\n selectedEngine?: string;\n selectedEffort?: ReasoningEffort;\n onModelChange?: (model: string, engine: string) => void;\n onEffortChange?: (effort: ReasoningEffort) => void;\n /**\n * Enable server-backed model/provider status checks. Defaults off when the\n * host supplies model state and callbacks, otherwise on.\n */\n modelStatusChecksEnabled?: boolean;\n /** Called whenever the plain editor text changes. */\n onTextChange?: (text: string) => void;\n /**\n * Override the Builder.io connect action in the model picker. When provided,\n * clicking \"Connect Builder.io\" calls this instead of opening a browser popup.\n * Used by the Electron desktop app to route through the native IPC handler.\n */\n onConnectProvider?: () => void;\n /** Imperative handle for focusing the composer. */\n composerRef?: Ref<TiptapComposerHandle>;\n}\n\n// Minimal pass-through adapter. PromptComposer always submits through\n// onSubmitOverride, so the runtime never actually calls this — but\n// `useLocalRuntime` needs *something* shaped like a ChatModelAdapter.\nconst NOOP_ADAPTER: ChatModelAdapter = {\n async *run() {\n return;\n },\n};\n\n/**\n * Local binary document adapter so reference PDFs, decks, and docs can be\n * attached without dragging the whole assistant chat module into bundles that\n * just want a prompt popover.\n */\nclass BinaryDocumentAttachmentAdapter implements AttachmentAdapter {\n public accept = PROMPT_DOCUMENT_ATTACHMENT_ACCEPT;\n\n public async add(state: { file: File }): Promise<PendingAttachment> {\n return {\n id: state.file.name,\n type: \"document\",\n name: state.file.name,\n contentType: state.file.type || \"application/octet-stream\",\n file: state.file,\n status: { type: \"requires-action\", reason: \"composer-send\" },\n };\n }\n\n public async send(\n attachment: PendingAttachment,\n ): Promise<CompleteAttachment> {\n return {\n ...attachment,\n status: { type: \"complete\" },\n content: [],\n };\n }\n\n public async remove() {\n /* noop */\n }\n}\n\nclass RasterImageAttachmentAdapter extends SimpleImageAttachmentAdapter {\n public accept = IMAGE_ATTACHMENT_ACCEPT;\n}\n\nfunction isInlineableTextFile(file: File): boolean {\n if (file.type.startsWith(\"text/\")) return true;\n if (file.type === \"application/json\") return true;\n return /\\.(txt|md|markdown|csv|json|yaml|yml|html?|css|xml)$/i.test(\n file.name,\n );\n}\n\nfunction formatInlineTextFile(name: string, text: string): string {\n const truncated = text.length > MAX_INLINE_TEXT_FILE_CHARS;\n const body = truncated ? text.slice(0, MAX_INLINE_TEXT_FILE_CHARS) : text;\n return [\n `<uploaded-text-file name=\"${escapePromptAttachmentAttribute(name)}\">`,\n body,\n truncated\n ? `[Truncated after ${MAX_INLINE_TEXT_FILE_CHARS} characters.]`\n : \"\",\n \"</uploaded-text-file>\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n}\n\nexport async function buildPromptComposerSubmission(options: {\n text: string;\n attachments?: ReadonlyArray<unknown>;\n}): Promise<{ text: string; files: File[] }> {\n const files: File[] = [];\n const pastedTextBlocks: string[] = [];\n const rawText = options.text;\n\n for (const att of options.attachments ?? []) {\n const a = att as Attachment;\n if (\"file\" in a && a.file instanceof File) {\n const file = a.file;\n if (isPastedTextAttachmentName(file.name)) {\n try {\n pastedTextBlocks.push(await file.text());\n } catch {\n files.push(file);\n }\n } else {\n if (isInlineableTextFile(file)) {\n try {\n pastedTextBlocks.push(\n formatInlineTextFile(file.name, await file.text()),\n );\n } catch {\n // Keep the upload path fallback below.\n }\n }\n // Note: images are NOT inlined into the prompt text even when small.\n // Inlining a base64 data-URL into a text string consumes an enormous\n // number of tokens (≈ 700 K per MB) and most hosts handle images via\n // proper attachment channels. The `files` array below carries the image\n // for the host to process through a dedicated attachment pipeline.\n files.push(file);\n }\n }\n }\n\n return {\n text: pastedTextBlocks.length\n ? [rawText.trim(), ...pastedTextBlocks].filter(Boolean).join(\"\\n\\n\")\n : rawText,\n files,\n };\n}\n\nfunction getImageSrc(attachment: Attachment): string | null {\n if (attachment.type !== \"image\") return null;\n if (\"file\" in attachment && attachment.file) {\n return URL.createObjectURL(attachment.file);\n }\n const imagePart = attachment.content?.find((part) => part.type === \"image\");\n return imagePart && \"image\" in imagePart ? imagePart.image : null;\n}\n\nfunction ImagePreviewLightbox({\n src,\n alt,\n onClose,\n}: {\n src: string;\n alt: string;\n onClose: () => void;\n}) {\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", handler);\n document.body.style.overflow = \"hidden\";\n return () => {\n document.removeEventListener(\"keydown\", handler);\n document.body.style.overflow = \"\";\n };\n }, [onClose]);\n\n return (\n <div\n role=\"dialog\"\n aria-label=\"Image preview\"\n onClick={onClose}\n className=\"fixed inset-0 z-[300] flex items-center justify-center bg-black/80 p-6 cursor-zoom-out\"\n >\n <img\n src={src}\n alt={alt}\n onClick={(e) => e.stopPropagation()}\n className=\"max-h-full max-w-full object-contain rounded-md shadow-2xl cursor-default\"\n />\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Close preview\"\n className=\"absolute right-4 top-4 flex h-8 w-8 cursor-pointer items-center justify-center rounded-full border border-white/30 bg-black/40 text-white hover:bg-black/60\"\n >\n <IconX className=\"h-4 w-4\" />\n </button>\n </div>\n );\n}\n\nfunction AttachmentChip({\n attachment,\n onRemove,\n}: {\n attachment: Attachment;\n onRemove: (id: string) => void;\n}) {\n const src = useMemo(() => getImageSrc(attachment), [attachment]);\n const [previewOpen, setPreviewOpen] = useState(false);\n useEffect(\n () => () => {\n if (src?.startsWith(\"blob:\")) URL.revokeObjectURL(src);\n },\n [src],\n );\n\n if (isPastedTextAttachmentName(attachment.name)) {\n return <PastedTextChip attachment={attachment} onRemove={onRemove} />;\n }\n\n if (src) {\n return (\n <>\n <button\n type=\"button\"\n onClick={() => setPreviewOpen(true)}\n aria-label={`Preview ${attachment.name}`}\n className=\"agent-composer-attachment-image group relative flex h-16 min-w-16 max-w-28 cursor-zoom-in items-center justify-center overflow-hidden rounded-lg border border-border/70 bg-muted/50\"\n >\n <img\n src={src}\n alt={attachment.name}\n className=\"max-h-full max-w-full object-contain p-1\"\n />\n <span\n role=\"button\"\n tabIndex={0}\n onClick={(e) => {\n e.stopPropagation();\n onRemove(attachment.id);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n e.stopPropagation();\n onRemove(attachment.id);\n }\n }}\n aria-label={`Remove ${attachment.name}`}\n className=\"absolute right-1 top-1 flex h-5 w-5 cursor-pointer items-center justify-center rounded-full border border-border/60 bg-background/90 text-muted-foreground hover:text-foreground\"\n >\n <IconX className=\"h-3 w-3\" />\n </span>\n </button>\n {previewOpen ? (\n <ImagePreviewLightbox\n src={src}\n alt={attachment.name}\n onClose={() => setPreviewOpen(false)}\n />\n ) : null}\n </>\n );\n }\n\n return (\n <div className=\"agent-composer-attachment-chip group relative inline-flex max-w-[200px] items-center gap-2 rounded-md border border-border/70 bg-muted/50 px-2 py-1.5 text-xs\">\n <div className=\"flex h-6 w-6 shrink-0 items-center justify-center rounded bg-background text-[9px] font-semibold uppercase text-muted-foreground\">\n {attachment.name.split(\".\").pop() || \"file\"}\n </div>\n <span className=\"min-w-0 truncate font-medium\">{attachment.name}</span>\n <button\n type=\"button\"\n onClick={() => onRemove(attachment.id)}\n aria-label={`Remove ${attachment.name}`}\n className=\"flex h-5 w-5 shrink-0 cursor-pointer items-center justify-center rounded text-muted-foreground hover:text-foreground\"\n >\n <IconX className=\"h-3 w-3\" />\n </button>\n </div>\n );\n}\n\nfunction PromptAttachmentStrip() {\n const attachments = useComposer((state) => state.attachments);\n const aui = useAui();\n\n const handleRemove = useCallback(\n (id: string) => {\n void aui.composer().attachment({ id }).remove();\n },\n [aui],\n );\n\n if (attachments.length === 0) return null;\n return (\n <div className=\"agent-composer-attachment-strip flex flex-wrap gap-2 px-2 pt-2\">\n {attachments.map((attachment) => (\n <AttachmentChip\n key={attachment.id}\n attachment={attachment}\n onRemove={handleRemove}\n />\n ))}\n </div>\n );\n}\n\nfunction PromptComposerInner({\n onSubmit,\n placeholder,\n disabled,\n autoFocus,\n className,\n style,\n rootClassName,\n rootStyle,\n draftScope,\n preserveDraftOnSubmit = false,\n showModelSelector = true,\n voiceEnabled = DEFAULT_VOICE_DICTATION_ENABLED,\n attachmentsEnabled = true,\n plusMenuMode,\n initialText,\n initialTextKey,\n modeControl,\n toolbarSlot,\n attachButton,\n actionButton,\n extraActionButton,\n layoutVariant,\n slashCommands,\n slashSkills,\n includeDefaultSlashCommands,\n includeDefaultSlashSkills,\n onSlashCommand,\n availableModels,\n selectedModel,\n selectedEngine,\n selectedEffort,\n onModelChange,\n onEffortChange,\n modelStatusChecksEnabled,\n onTextChange,\n onConnectProvider,\n composerRef,\n}: PromptComposerProps) {\n const localRef = useRef<TiptapComposerHandle>(null);\n const handleRef = composerRef ?? localRef;\n const hostManagedModels = Boolean(\n availableModels && selectedModel && onModelChange,\n );\n const resolvedModelStatusChecksEnabled =\n modelStatusChecksEnabled ?? !hostManagedModels;\n const models = useChatModels({\n enabled: showModelSelector && resolvedModelStatusChecksEnabled,\n });\n const composerModel = showModelSelector\n ? (selectedModel ?? models.selectedModel)\n : undefined;\n const composerEngine = showModelSelector\n ? (selectedEngine ?? models.selectedEngine)\n : undefined;\n const composerEffort = showModelSelector\n ? (selectedEffort ?? models.selectedEffort)\n : undefined;\n const composerModelGroups = showModelSelector\n ? (availableModels ?? models.availableModels)\n : undefined;\n const handleModelChange = showModelSelector\n ? (onModelChange ?? models.onModelChange)\n : undefined;\n const handleEffortChange = showModelSelector\n ? (onEffortChange ?? models.onEffortChange)\n : undefined;\n\n useEffect(() => {\n if (!autoFocus) return;\n const id = window.setTimeout(() => {\n const target =\n typeof handleRef === \"object\" && handleRef && \"current\" in handleRef\n ? handleRef.current\n : null;\n target?.focus();\n }, 50);\n return () => window.clearTimeout(id);\n }, [autoFocus, handleRef]);\n\n const handleSubmit = useCallback(\n async (\n text: string,\n references: Reference[],\n attachments?: ReadonlyArray<unknown>,\n submitOptions?: TiptapComposerSubmitOptions,\n ) => {\n // PromptComposer hosts (NewWorkspaceAppFlow, create-extension, create-deck,\n // …) submit a single string prompt — they don't run the assistant-ui\n // attachment send pipeline. TiptapComposer auto-converts large pastes\n // into a \"Pasted text\" chip, which would otherwise disappear into an\n // unprocessed File. Inline the chip body back into the prompt text so\n // newlines and full content survive the round-trip.\n const { text: finalText, files } = await buildPromptComposerSubmission({\n text,\n attachments,\n });\n onSubmit(finalText, files, references, {\n intent: submitOptions?.intent ?? \"immediate\",\n model: composerModel,\n engine: composerEngine,\n effort: composerEffort,\n });\n },\n [composerEffort, composerEngine, composerModel, onSubmit],\n );\n\n return (\n <AgentComposerFrame\n className={cn(\"text-left\", className)}\n rootClassName={rootClassName}\n style={style}\n rootStyle={rootStyle}\n layoutVariant={layoutVariant}\n >\n <PromptAttachmentStrip />\n <TiptapComposer\n focusRef={handleRef}\n disabled={disabled}\n placeholder={placeholder}\n initialText={initialText}\n initialTextKey={initialTextKey}\n onSubmit={handleSubmit}\n clearOnSubmit={!preserveDraftOnSubmit}\n plusMenuMode={\n plusMenuMode ?? (attachmentsEnabled ? \"upload-only\" : \"hidden\")\n }\n attachButton={attachButton}\n modeControl={modeControl}\n toolbarSlot={toolbarSlot}\n actionButton={actionButton}\n extraActionButton={extraActionButton}\n layoutVariant={layoutVariant}\n slashCommands={slashCommands}\n slashSkills={slashSkills}\n includeDefaultSlashCommands={includeDefaultSlashCommands}\n includeDefaultSlashSkills={includeDefaultSlashSkills}\n onSlashCommand={onSlashCommand}\n voiceEnabled={voiceEnabled}\n onTextChange={onTextChange}\n draftScope={draftScope}\n selectedModel={composerModel}\n selectedEffort={composerEffort}\n availableModels={composerModelGroups}\n onModelChange={handleModelChange}\n onEffortChange={handleEffortChange}\n providerConnectStatusEnabled={resolvedModelStatusChecksEnabled}\n onConnectProvider={onConnectProvider}\n />\n </AgentComposerFrame>\n );\n}\n\n/**\n * Standalone composer that mirrors the agent sidebar's input experience —\n * voice dictation, file upload, model selector, submit-on-Enter — for use in\n * popovers and inline prompt forms (create tool, create deck, create dashboard,\n * the Dispatch new-app flow, etc.).\n *\n * The host owns submission: when the user presses Enter or clicks submit,\n * `onSubmit(text, files, references, options)` is called. PromptComposer runs\n * its own minimal assistant-ui runtime so it can be dropped into any subtree\n * without needing the outer chat to be mounted.\n */\nexport function PromptComposer(props: PromptComposerProps) {\n const attachmentAdapter = useMemo(\n () =>\n new CompositeAttachmentAdapter([\n new RasterImageAttachmentAdapter(),\n new BinaryDocumentAttachmentAdapter(),\n new TextAttachmentAdapter(),\n ]),\n [],\n );\n const runtime = useLocalRuntime(NOOP_ADAPTER, {\n adapters: { attachments: attachmentAdapter },\n });\n const resetKey = [\n props.draftScope ?? \"\",\n props.initialTextKey ?? \"\",\n props.initialText ?? \"\",\n ].join(\":\");\n\n return (\n <TooltipProvider delayDuration={200}>\n <AssistantRuntimeProvider runtime={runtime}>\n <ThreadPrimitive.Root\n className=\"contents\"\n style={{ display: \"contents\" }}\n >\n <AssistantUiStaleIndexErrorBoundary\n resetKey={resetKey}\n componentName=\"PromptComposer\"\n >\n <PromptComposerInner {...props} />\n </AssistantUiStaleIndexErrorBoundary>\n </ThreadPrimitive.Root>\n </AssistantRuntimeProvider>\n </TooltipProvider>\n );\n}\n"]}
@@ -1,5 +1,7 @@
1
1
  import { SimpleTextAttachmentAdapter } from "@assistant-ui/react";
2
2
  export declare const PROMPT_DOCUMENT_ATTACHMENT_ACCEPT: string;
3
+ export declare const CHAT_DOCUMENT_ATTACHMENT_ACCEPT: string;
4
+ export declare const IMAGE_ATTACHMENT_ACCEPT: string;
3
5
  export declare const TEXT_ATTACHMENT_ACCEPT: string;
4
6
  export declare class TextAttachmentAdapter extends SimpleTextAttachmentAdapter {
5
7
  accept: string;
@@ -1 +1 @@
1
- {"version":3,"file":"attachment-accept.d.ts","sourceRoot":"","sources":["../../../src/client/composer/attachment-accept.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAElE,eAAO,MAAM,iCAAiC,QAOnC,CAAC;AAEZ,eAAO,MAAM,sBAAsB,QAsBxB,CAAC;AAEZ,qBAAa,qBAAsB,SAAQ,2BAA2B;IAC7D,MAAM,SAA0B;CACxC"}
1
+ {"version":3,"file":"attachment-accept.d.ts","sourceRoot":"","sources":["../../../src/client/composer/attachment-accept.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAWlE,eAAO,MAAM,iCAAiC,QACH,CAAC;AAE5C,eAAO,MAAM,+BAA+B,QAIjC,CAAC;AAEZ,eAAO,MAAM,uBAAuB,QAsBzB,CAAC;AAEZ,eAAO,MAAM,sBAAsB,QAsBxB,CAAC;AAEZ,qBAAa,qBAAsB,SAAQ,2BAA2B;IAC7D,MAAM,SAA0B;CACxC"}
@@ -1,11 +1,40 @@
1
1
  import { SimpleTextAttachmentAdapter } from "@assistant-ui/react";
2
- export const PROMPT_DOCUMENT_ATTACHMENT_ACCEPT = [
2
+ const BASE_DOCUMENT_ATTACHMENT_ACCEPT = [
3
3
  "application/pdf",
4
4
  "application/vnd.openxmlformats-officedocument.presentationml.presentation",
5
5
  "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
6
6
  ".pdf",
7
7
  ".pptx",
8
8
  ".docx",
9
+ ];
10
+ export const PROMPT_DOCUMENT_ATTACHMENT_ACCEPT = BASE_DOCUMENT_ATTACHMENT_ACCEPT.join(",");
11
+ export const CHAT_DOCUMENT_ATTACHMENT_ACCEPT = [
12
+ ...BASE_DOCUMENT_ATTACHMENT_ACCEPT,
13
+ "image/svg+xml",
14
+ ".svg",
15
+ ].join(",");
16
+ export const IMAGE_ATTACHMENT_ACCEPT = [
17
+ "image/jpeg",
18
+ "image/jpg",
19
+ "image/png",
20
+ "image/gif",
21
+ "image/webp",
22
+ "image/heic",
23
+ "image/heif",
24
+ "image/avif",
25
+ "image/bmp",
26
+ "image/tiff",
27
+ ".jpg",
28
+ ".jpeg",
29
+ ".png",
30
+ ".gif",
31
+ ".webp",
32
+ ".heic",
33
+ ".heif",
34
+ ".avif",
35
+ ".bmp",
36
+ ".tif",
37
+ ".tiff",
9
38
  ].join(",");
10
39
  export const TEXT_ATTACHMENT_ACCEPT = [
11
40
  "text/plain",
@@ -1 +1 @@
1
- {"version":3,"file":"attachment-accept.js","sourceRoot":"","sources":["../../../src/client/composer/attachment-accept.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAElE,MAAM,CAAC,MAAM,iCAAiC,GAAG;IAC/C,iBAAiB;IACjB,2EAA2E;IAC3E,yEAAyE;IACzE,MAAM;IACN,OAAO;IACP,OAAO;CACR,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEZ,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,YAAY;IACZ,WAAW;IACX,eAAe;IACf,UAAU;IACV,UAAU;IACV,WAAW;IACX,UAAU;IACV,WAAW;IACX,kBAAkB;IAClB,oBAAoB;IACpB,MAAM;IACN,KAAK;IACL,WAAW;IACX,MAAM;IACN,OAAO;IACP,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;CACP,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEZ,MAAM,OAAO,qBAAsB,SAAQ,2BAA2B;IAC7D,MAAM,GAAG,sBAAsB,CAAC;CACxC","sourcesContent":["import { SimpleTextAttachmentAdapter } from \"@assistant-ui/react\";\n\nexport const PROMPT_DOCUMENT_ATTACHMENT_ACCEPT = [\n \"application/pdf\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \".pdf\",\n \".pptx\",\n \".docx\",\n].join(\",\");\n\nexport const TEXT_ATTACHMENT_ACCEPT = [\n \"text/plain\",\n \"text/html\",\n \"text/markdown\",\n \"text/csv\",\n \"text/xml\",\n \"text/json\",\n \"text/css\",\n \"text/yaml\",\n \"application/json\",\n \"application/x-yaml\",\n \".txt\",\n \".md\",\n \".markdown\",\n \".csv\",\n \".json\",\n \".html\",\n \".htm\",\n \".css\",\n \".xml\",\n \".yaml\",\n \".yml\",\n].join(\",\");\n\nexport class TextAttachmentAdapter extends SimpleTextAttachmentAdapter {\n public accept = TEXT_ATTACHMENT_ACCEPT;\n}\n"]}
1
+ {"version":3,"file":"attachment-accept.js","sourceRoot":"","sources":["../../../src/client/composer/attachment-accept.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAElE,MAAM,+BAA+B,GAAG;IACtC,iBAAiB;IACjB,2EAA2E;IAC3E,yEAAyE;IACzE,MAAM;IACN,OAAO;IACP,OAAO;CACR,CAAC;AAEF,MAAM,CAAC,MAAM,iCAAiC,GAC5C,+BAA+B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE5C,MAAM,CAAC,MAAM,+BAA+B,GAAG;IAC7C,GAAG,+BAA+B;IAClC,eAAe;IACf,MAAM;CACP,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEZ,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,YAAY;IACZ,WAAW;IACX,WAAW;IACX,WAAW;IACX,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,WAAW;IACX,YAAY;IACZ,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;CACR,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEZ,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,YAAY;IACZ,WAAW;IACX,eAAe;IACf,UAAU;IACV,UAAU;IACV,WAAW;IACX,UAAU;IACV,WAAW;IACX,kBAAkB;IAClB,oBAAoB;IACpB,MAAM;IACN,KAAK;IACL,WAAW;IACX,MAAM;IACN,OAAO;IACP,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;CACP,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEZ,MAAM,OAAO,qBAAsB,SAAQ,2BAA2B;IAC7D,MAAM,GAAG,sBAAsB,CAAC;CACxC","sourcesContent":["import { SimpleTextAttachmentAdapter } from \"@assistant-ui/react\";\n\nconst BASE_DOCUMENT_ATTACHMENT_ACCEPT = [\n \"application/pdf\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \".pdf\",\n \".pptx\",\n \".docx\",\n];\n\nexport const PROMPT_DOCUMENT_ATTACHMENT_ACCEPT =\n BASE_DOCUMENT_ATTACHMENT_ACCEPT.join(\",\");\n\nexport const CHAT_DOCUMENT_ATTACHMENT_ACCEPT = [\n ...BASE_DOCUMENT_ATTACHMENT_ACCEPT,\n \"image/svg+xml\",\n \".svg\",\n].join(\",\");\n\nexport const IMAGE_ATTACHMENT_ACCEPT = [\n \"image/jpeg\",\n \"image/jpg\",\n \"image/png\",\n \"image/gif\",\n \"image/webp\",\n \"image/heic\",\n \"image/heif\",\n \"image/avif\",\n \"image/bmp\",\n \"image/tiff\",\n \".jpg\",\n \".jpeg\",\n \".png\",\n \".gif\",\n \".webp\",\n \".heic\",\n \".heif\",\n \".avif\",\n \".bmp\",\n \".tif\",\n \".tiff\",\n].join(\",\");\n\nexport const TEXT_ATTACHMENT_ACCEPT = [\n \"text/plain\",\n \"text/html\",\n \"text/markdown\",\n \"text/csv\",\n \"text/xml\",\n \"text/json\",\n \"text/css\",\n \"text/yaml\",\n \"application/json\",\n \"application/x-yaml\",\n \".txt\",\n \".md\",\n \".markdown\",\n \".csv\",\n \".json\",\n \".html\",\n \".htm\",\n \".css\",\n \".xml\",\n \".yaml\",\n \".yml\",\n].join(\",\");\n\nexport class TextAttachmentAdapter extends SimpleTextAttachmentAdapter {\n public accept = TEXT_ATTACHMENT_ACCEPT;\n}\n"]}
@@ -103,9 +103,9 @@ export declare const dataTableWidgetSchema: z.ZodObject<{
103
103
  }, z.core.$loose>;
104
104
  export declare const dataChartWidgetSchema: z.ZodObject<{
105
105
  type: z.ZodEnum<{
106
- area: "area";
107
106
  bar: "bar";
108
107
  line: "line";
108
+ area: "area";
109
109
  }>;
110
110
  title: z.ZodOptional<z.ZodString>;
111
111
  xKey: z.ZodString;
@@ -161,9 +161,9 @@ export declare const dataChartWidgetResultSchema: z.ZodObject<{
161
161
  widget: z.ZodLiteral<"data-chart">;
162
162
  chartSeries: z.ZodObject<{
163
163
  type: z.ZodEnum<{
164
- area: "area";
165
164
  bar: "bar";
166
165
  line: "line";
166
+ area: "area";
167
167
  }>;
168
168
  title: z.ZodOptional<z.ZodString>;
169
169
  xKey: z.ZodString;
@@ -206,9 +206,9 @@ export declare const dataInsightsWidgetResultSchema: z.ZodObject<{
206
206
  }, z.core.$loose>>;
207
207
  chartSeries: z.ZodOptional<z.ZodObject<{
208
208
  type: z.ZodEnum<{
209
- area: "area";
210
209
  bar: "bar";
211
210
  line: "line";
211
+ area: "area";
212
212
  }>;
213
213
  title: z.ZodOptional<z.ZodString>;
214
214
  xKey: z.ZodString;
@@ -264,9 +264,9 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
264
264
  widget: z.ZodLiteral<"data-chart">;
265
265
  chartSeries: z.ZodObject<{
266
266
  type: z.ZodEnum<{
267
- area: "area";
268
267
  bar: "bar";
269
268
  line: "line";
269
+ area: "area";
270
270
  }>;
271
271
  title: z.ZodOptional<z.ZodString>;
272
272
  xKey: z.ZodString;
@@ -308,9 +308,9 @@ export declare const dataWidgetResultSchema: z.ZodUnion<readonly [z.ZodObject<{
308
308
  }, z.core.$loose>>;
309
309
  chartSeries: z.ZodOptional<z.ZodObject<{
310
310
  type: z.ZodEnum<{
311
- area: "area";
312
311
  bar: "bar";
313
312
  line: "line";
313
+ area: "area";
314
314
  }>;
315
315
  title: z.ZodOptional<z.ZodString>;
316
316
  xKey: z.ZodString;
@@ -16,6 +16,8 @@ export interface PreUploadedFileAttachment {
16
16
  provider: string;
17
17
  contentType?: string;
18
18
  sizeBytes?: number;
19
+ referenceOnly?: boolean;
20
+ securityNote?: string;
19
21
  }
20
22
  export interface PreUploadAttachmentsResult {
21
23
  /** Same array reference. Each image attachment that was uploaded also gets a
@@ -1 +1 @@
1
- {"version":3,"file":"pre-upload-attachments.d.ts","sourceRoot":"","sources":["../../src/file-upload/pre-upload-attachments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAG7D,MAAM,WAAW,0BAA0B;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,0BAA0B;IACzC;;uBAEmB;IACnB,WAAW,EAAE,mBAAmB,EAAE,CAAC;IACnC;4DACwD;IACxD,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC;qDACiD;IACjD,aAAa,EAAE,yBAAyB,EAAE,CAAC;IAC3C;;2CAEuC;IACvC,eAAe,EAAE,OAAO,CAAC;IACzB;;yBAEqB;IACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAaD;;;GAGG;AACH,wBAAgB,8BAA8B,IAAI,OAAO,CAExD;AAED;;;;;;;;;GASG;AACH,wBAAsB,yBAAyB,CAAC,IAAI,EAAE;IACpD,WAAW,EAAE,mBAAmB,EAAE,GAAG,SAAS,CAAC;IAC/C,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACvC,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAEtC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,WAAW,EAAE,mBAAmB,EAAE,GAAG,SAAS,CAAC;IAC/C,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACtC,6EAA6E;IAC7E,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAgItC"}
1
+ {"version":3,"file":"pre-upload-attachments.d.ts","sourceRoot":"","sources":["../../src/file-upload/pre-upload-attachments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAG7D,MAAM,WAAW,0BAA0B;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,0BAA0B;IACzC;;uBAEmB;IACnB,WAAW,EAAE,mBAAmB,EAAE,CAAC;IACnC;4DACwD;IACxD,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC;qDACiD;IACjD,aAAa,EAAE,yBAAyB,EAAE,CAAC;IAC3C;;2CAEuC;IACvC,eAAe,EAAE,OAAO,CAAC;IACzB;;yBAEqB;IACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAoDD;;;GAGG;AACH,wBAAgB,8BAA8B,IAAI,OAAO,CAExD;AAED;;;;;;;;;GASG;AACH,wBAAsB,yBAAyB,CAAC,IAAI,EAAE;IACpD,WAAW,EAAE,mBAAmB,EAAE,GAAG,SAAS,CAAC;IAC/C,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACvC,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAEtC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,WAAW,EAAE,mBAAmB,EAAE,GAAG,SAAS,CAAC;IAC/C,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACtC,6EAA6E;IAC7E,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAuKtC"}