@copilotkit/shared 1.55.0-next.9 → 1.55.1-next.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 (53) hide show
  1. package/CHANGELOG.md +13 -1
  2. package/dist/a2ui-prompts.cjs +106 -0
  3. package/dist/a2ui-prompts.cjs.map +1 -0
  4. package/dist/a2ui-prompts.d.cts +20 -0
  5. package/dist/a2ui-prompts.d.cts.map +1 -0
  6. package/dist/a2ui-prompts.d.mts +20 -0
  7. package/dist/a2ui-prompts.d.mts.map +1 -0
  8. package/dist/a2ui-prompts.mjs +104 -0
  9. package/dist/a2ui-prompts.mjs.map +1 -0
  10. package/dist/attachments/types.d.cts +54 -0
  11. package/dist/attachments/types.d.cts.map +1 -0
  12. package/dist/attachments/types.d.mts +54 -0
  13. package/dist/attachments/types.d.mts.map +1 -0
  14. package/dist/attachments/utils.cjs +134 -0
  15. package/dist/attachments/utils.cjs.map +1 -0
  16. package/dist/attachments/utils.d.cts +42 -0
  17. package/dist/attachments/utils.d.cts.map +1 -0
  18. package/dist/attachments/utils.d.mts +42 -0
  19. package/dist/attachments/utils.d.mts.map +1 -0
  20. package/dist/attachments/utils.mjs +126 -0
  21. package/dist/attachments/utils.mjs.map +1 -0
  22. package/dist/index.cjs +29 -8
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +20 -3
  25. package/dist/index.d.cts.map +1 -1
  26. package/dist/index.d.mts +20 -3
  27. package/dist/index.d.mts.map +1 -1
  28. package/dist/index.mjs +19 -3
  29. package/dist/index.mjs.map +1 -1
  30. package/dist/index.umd.js +259 -9
  31. package/dist/index.umd.js.map +1 -1
  32. package/dist/package.cjs +1 -1
  33. package/dist/package.mjs +1 -1
  34. package/dist/types/message.d.cts +15 -4
  35. package/dist/types/message.d.cts.map +1 -1
  36. package/dist/types/message.d.mts +15 -4
  37. package/dist/types/message.d.mts.map +1 -1
  38. package/dist/utils/types.cjs.map +1 -1
  39. package/dist/utils/types.d.cts +1 -0
  40. package/dist/utils/types.d.cts.map +1 -1
  41. package/dist/utils/types.d.mts +1 -0
  42. package/dist/utils/types.d.mts.map +1 -1
  43. package/dist/utils/types.mjs.map +1 -1
  44. package/package.json +33 -34
  45. package/src/a2ui-prompts.ts +101 -0
  46. package/src/attachments/__tests__/utils.test.ts +198 -0
  47. package/src/attachments/index.ts +19 -0
  48. package/src/attachments/types.ts +67 -0
  49. package/src/attachments/utils.ts +164 -0
  50. package/src/index.ts +43 -1
  51. package/src/types/__tests__/message.test.ts +62 -0
  52. package/src/types/message.ts +27 -3
  53. package/src/utils/types.ts +1 -0
package/CHANGELOG.md CHANGED
@@ -1,6 +1,18 @@
1
1
  # @copilotkit/shared
2
2
 
3
- ## 1.55.0-next.9
3
+ ## 1.55.1-next.0
4
+
5
+ ## 1.55.0
6
+
7
+ ### Minor Changes
8
+
9
+ - 1ceb963: refactor: consolidate V1/V2 packages into flat @copilotkit/\* structure
10
+ - 5289791: feat: add multimodal attachment support to the builtin agent
11
+
12
+ ### Patch Changes
13
+
14
+ - 52a9322: Fixing license warnings, barrel export and typing
15
+ - 434ccd8: A2UI v0.9 + Open Generative UI: BYOC catalogs, dark mode, sandboxed UI generation
4
16
 
5
17
  ## 1.55.0-next.8
6
18
 
@@ -0,0 +1,106 @@
1
+
2
+ //#region src/a2ui-prompts.ts
3
+ /**
4
+ * Default A2UI generation and design guideline prompts.
5
+ *
6
+ * These are the canonical prompt fragments that instruct an LLM how to call
7
+ * the render_a2ui tool, how to bind data, and how to style surfaces.
8
+ */
9
+ /**
10
+ * Generation guidelines — protocol rules, tool arguments, path rules,
11
+ * data model format, and form/two-way-binding instructions.
12
+ */
13
+ const A2UI_DEFAULT_GENERATION_GUIDELINES = `\
14
+ Generate A2UI v0.9 JSON.
15
+
16
+ ## A2UI Protocol Instructions
17
+
18
+ A2UI (Agent to UI) is a protocol for rendering rich UI surfaces from agent responses.
19
+
20
+ CRITICAL: You MUST call the render_a2ui tool with ALL of these arguments:
21
+ - surfaceId: A unique ID for the surface (e.g. "product-comparison")
22
+ - components: REQUIRED — the A2UI component array. NEVER omit this. Only use
23
+ components listed in the Available Components schema provided as context.
24
+ - data: OPTIONAL — a JSON object written to the root of the surface data model.
25
+ Use for pre-filling form values or providing data for path-bound components.
26
+ - every component must have the "component" field specifying the component type.
27
+ ONLY use component names from the Available Components schema — do NOT invent
28
+ component names or use names not in the schema.
29
+
30
+ COMPONENT ID RULES:
31
+ - Every component ID must be unique within the surface.
32
+ - A component MUST NOT reference itself as child/children. This causes a
33
+ circular dependency error. For example, if a component has id="avatar",
34
+ its child must be a DIFFERENT id (e.g. "avatar-img"), never "avatar".
35
+ - The child/children tree must be a DAG — no cycles allowed.
36
+
37
+ REPEATING CONTENT (TEMPLATES):
38
+ To repeat a component for each item in an array, use the structural children format:
39
+ children: { componentId: "card-id", path: "/items" }
40
+ This tells the renderer to create one instance of "card-id" per item in the "/items" array.
41
+
42
+ PATH RULES FOR TEMPLATES:
43
+ Components inside a repeating template use RELATIVE paths (no leading slash).
44
+ The path is resolved relative to each array item automatically.
45
+ If a container has children: { componentId: "card", path: "/items" } and each item
46
+ has a key "name", use { "path": "name" } (NO leading slash — relative to item).
47
+ CRITICAL: Do NOT use "/name" (absolute) inside templates — use "name" (relative).
48
+ The container's path ("/items") uses a leading slash (absolute), but all
49
+ components INSIDE the template use paths WITHOUT leading slash.
50
+
51
+ DATA MODEL:
52
+ The "data" key in the tool args is a plain JSON object that initializes the surface
53
+ data model. Components bound to paths (e.g. "value": { "path": "/form/name" })
54
+ read from and write to this data model. Examples:
55
+ For forms: "data": { "form": { "name": "Alice", "email": "" } }
56
+ For lists: "data": { "items": [{"name": "Product A"}, {"name": "Product B"}] }
57
+ For mixed: "data": { "form": { "query": "" }, "results": [...] }
58
+
59
+ FORMS AND TWO-WAY DATA BINDING:
60
+ To create editable forms, bind input components to data model paths using { "path": "..." }.
61
+ The client automatically writes user input back to the data model at the bound path.
62
+ CRITICAL: Using a literal value (e.g. "value": "") makes the field READ-ONLY.
63
+ You MUST use { "path": "..." } to make inputs editable.
64
+
65
+ Input components use "value" as the binding property:
66
+ "value": { "path": "/form/fieldName" }
67
+
68
+ To retrieve form values when a button is clicked, include "context" with path references
69
+ in the button's action. Paths are resolved to their current values at click time:
70
+ "action": { "event": { "name": "submit", "context": { "userName": { "path": "/form/name" } } } }
71
+
72
+ To pre-fill form values, pass initial data via the "data" tool argument:
73
+ "data": { "form": { "name": "Markus" } }`;
74
+ /**
75
+ * Design guidelines — visual design rules, component hierarchy tips,
76
+ * and action handler patterns.
77
+ */
78
+ const A2UI_DEFAULT_DESIGN_GUIDELINES = `\
79
+ Create polished, visually appealing interfaces. ONLY use components listed in the
80
+ Available Components schema — do NOT use component names that are not in the schema.
81
+
82
+ Design principles:
83
+ - Create clear visual hierarchy within cards and layouts.
84
+ - Keep cards clean — avoid clutter. Whitespace is good.
85
+ - Use consistent surfaceIds (lowercase, hyphenated).
86
+ - NEVER use the same ID for a component and its child — this creates a
87
+ circular dependency. E.g. if id="avatar", child must NOT be "avatar".
88
+ - For side-by-side comparisons, use a container with structural children
89
+ (children: { componentId, path }) to repeat a card template per data item.
90
+ - Include images when relevant (logos, icons, product photos):
91
+ - Prefer company logos via Google favicons: https://www.google.com/s2/favicons?domain=example.com&sz=128
92
+ - Do NOT invent Unsplash photo-IDs — they will 404. Only use real, known URLs.
93
+ - For buttons: action MUST use this exact nested format:
94
+ "action": { "event": { "name": "myAction", "context": { "key": "value" } } }
95
+ The "event" key holds an OBJECT with "name" (required) and "context" (optional).
96
+ Do NOT use a flat format like {"event": "name"} — "event" must be an object.
97
+ - For forms: every input MUST use path binding on the "value" property
98
+ (e.g. "value": { "path": "/form/name" }) to be editable. The submit button's
99
+ action context MUST reference the same paths to capture the user's input.
100
+
101
+ Use the SAME surfaceId as the main surface. Match action names to button action event names.`;
102
+
103
+ //#endregion
104
+ exports.A2UI_DEFAULT_DESIGN_GUIDELINES = A2UI_DEFAULT_DESIGN_GUIDELINES;
105
+ exports.A2UI_DEFAULT_GENERATION_GUIDELINES = A2UI_DEFAULT_GENERATION_GUIDELINES;
106
+ //# sourceMappingURL=a2ui-prompts.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a2ui-prompts.cjs","names":[],"sources":["../src/a2ui-prompts.ts"],"sourcesContent":["/**\n * Default A2UI generation and design guideline prompts.\n *\n * These are the canonical prompt fragments that instruct an LLM how to call\n * the render_a2ui tool, how to bind data, and how to style surfaces.\n */\n\n/**\n * Generation guidelines — protocol rules, tool arguments, path rules,\n * data model format, and form/two-way-binding instructions.\n */\nexport const A2UI_DEFAULT_GENERATION_GUIDELINES = `\\\nGenerate A2UI v0.9 JSON.\n\n## A2UI Protocol Instructions\n\nA2UI (Agent to UI) is a protocol for rendering rich UI surfaces from agent responses.\n\nCRITICAL: You MUST call the render_a2ui tool with ALL of these arguments:\n- surfaceId: A unique ID for the surface (e.g. \"product-comparison\")\n- components: REQUIRED — the A2UI component array. NEVER omit this. Only use\n components listed in the Available Components schema provided as context.\n- data: OPTIONAL — a JSON object written to the root of the surface data model.\n Use for pre-filling form values or providing data for path-bound components.\n- every component must have the \"component\" field specifying the component type.\n ONLY use component names from the Available Components schema — do NOT invent\n component names or use names not in the schema.\n\nCOMPONENT ID RULES:\n- Every component ID must be unique within the surface.\n- A component MUST NOT reference itself as child/children. This causes a\n circular dependency error. For example, if a component has id=\"avatar\",\n its child must be a DIFFERENT id (e.g. \"avatar-img\"), never \"avatar\".\n- The child/children tree must be a DAG — no cycles allowed.\n\nREPEATING CONTENT (TEMPLATES):\nTo repeat a component for each item in an array, use the structural children format:\n children: { componentId: \"card-id\", path: \"/items\" }\nThis tells the renderer to create one instance of \"card-id\" per item in the \"/items\" array.\n\nPATH RULES FOR TEMPLATES:\nComponents inside a repeating template use RELATIVE paths (no leading slash).\nThe path is resolved relative to each array item automatically.\nIf a container has children: { componentId: \"card\", path: \"/items\" } and each item\nhas a key \"name\", use { \"path\": \"name\" } (NO leading slash — relative to item).\nCRITICAL: Do NOT use \"/name\" (absolute) inside templates — use \"name\" (relative).\nThe container's path (\"/items\") uses a leading slash (absolute), but all\ncomponents INSIDE the template use paths WITHOUT leading slash.\n\nDATA MODEL:\nThe \"data\" key in the tool args is a plain JSON object that initializes the surface\ndata model. Components bound to paths (e.g. \"value\": { \"path\": \"/form/name\" })\nread from and write to this data model. Examples:\n For forms: \"data\": { \"form\": { \"name\": \"Alice\", \"email\": \"\" } }\n For lists: \"data\": { \"items\": [{\"name\": \"Product A\"}, {\"name\": \"Product B\"}] }\n For mixed: \"data\": { \"form\": { \"query\": \"\" }, \"results\": [...] }\n\nFORMS AND TWO-WAY DATA BINDING:\nTo create editable forms, bind input components to data model paths using { \"path\": \"...\" }.\nThe client automatically writes user input back to the data model at the bound path.\nCRITICAL: Using a literal value (e.g. \"value\": \"\") makes the field READ-ONLY.\nYou MUST use { \"path\": \"...\" } to make inputs editable.\n\nInput components use \"value\" as the binding property:\n \"value\": { \"path\": \"/form/fieldName\" }\n\nTo retrieve form values when a button is clicked, include \"context\" with path references\nin the button's action. Paths are resolved to their current values at click time:\n \"action\": { \"event\": { \"name\": \"submit\", \"context\": { \"userName\": { \"path\": \"/form/name\" } } } }\n\nTo pre-fill form values, pass initial data via the \"data\" tool argument:\n \"data\": { \"form\": { \"name\": \"Markus\" } }`;\n\n/**\n * Design guidelines — visual design rules, component hierarchy tips,\n * and action handler patterns.\n */\nexport const A2UI_DEFAULT_DESIGN_GUIDELINES = `\\\nCreate polished, visually appealing interfaces. ONLY use components listed in the\nAvailable Components schema — do NOT use component names that are not in the schema.\n\nDesign principles:\n- Create clear visual hierarchy within cards and layouts.\n- Keep cards clean — avoid clutter. Whitespace is good.\n- Use consistent surfaceIds (lowercase, hyphenated).\n- NEVER use the same ID for a component and its child — this creates a\n circular dependency. E.g. if id=\"avatar\", child must NOT be \"avatar\".\n- For side-by-side comparisons, use a container with structural children\n (children: { componentId, path }) to repeat a card template per data item.\n- Include images when relevant (logos, icons, product photos):\n - Prefer company logos via Google favicons: https://www.google.com/s2/favicons?domain=example.com&sz=128\n - Do NOT invent Unsplash photo-IDs — they will 404. Only use real, known URLs.\n- For buttons: action MUST use this exact nested format:\n \"action\": { \"event\": { \"name\": \"myAction\", \"context\": { \"key\": \"value\" } } }\n The \"event\" key holds an OBJECT with \"name\" (required) and \"context\" (optional).\n Do NOT use a flat format like {\"event\": \"name\"} — \"event\" must be an object.\n- For forms: every input MUST use path binding on the \"value\" property\n (e.g. \"value\": { \"path\": \"/form/name\" }) to be editable. The submit button's\n action context MUST reference the same paths to capture the user's input.\n\nUse the SAME surfaceId as the main surface. Match action names to button action event names.`;\n"],"mappings":";;;;;;;;;;;;AAWA,MAAa,qCAAqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkElD,MAAa,iCAAiC"}
@@ -0,0 +1,20 @@
1
+ //#region src/a2ui-prompts.d.ts
2
+ /**
3
+ * Default A2UI generation and design guideline prompts.
4
+ *
5
+ * These are the canonical prompt fragments that instruct an LLM how to call
6
+ * the render_a2ui tool, how to bind data, and how to style surfaces.
7
+ */
8
+ /**
9
+ * Generation guidelines — protocol rules, tool arguments, path rules,
10
+ * data model format, and form/two-way-binding instructions.
11
+ */
12
+ declare const A2UI_DEFAULT_GENERATION_GUIDELINES = "Generate A2UI v0.9 JSON.\n\n## A2UI Protocol Instructions\n\nA2UI (Agent to UI) is a protocol for rendering rich UI surfaces from agent responses.\n\nCRITICAL: You MUST call the render_a2ui tool with ALL of these arguments:\n- surfaceId: A unique ID for the surface (e.g. \"product-comparison\")\n- components: REQUIRED \u2014 the A2UI component array. NEVER omit this. Only use\n components listed in the Available Components schema provided as context.\n- data: OPTIONAL \u2014 a JSON object written to the root of the surface data model.\n Use for pre-filling form values or providing data for path-bound components.\n- every component must have the \"component\" field specifying the component type.\n ONLY use component names from the Available Components schema \u2014 do NOT invent\n component names or use names not in the schema.\n\nCOMPONENT ID RULES:\n- Every component ID must be unique within the surface.\n- A component MUST NOT reference itself as child/children. This causes a\n circular dependency error. For example, if a component has id=\"avatar\",\n its child must be a DIFFERENT id (e.g. \"avatar-img\"), never \"avatar\".\n- The child/children tree must be a DAG \u2014 no cycles allowed.\n\nREPEATING CONTENT (TEMPLATES):\nTo repeat a component for each item in an array, use the structural children format:\n children: { componentId: \"card-id\", path: \"/items\" }\nThis tells the renderer to create one instance of \"card-id\" per item in the \"/items\" array.\n\nPATH RULES FOR TEMPLATES:\nComponents inside a repeating template use RELATIVE paths (no leading slash).\nThe path is resolved relative to each array item automatically.\nIf a container has children: { componentId: \"card\", path: \"/items\" } and each item\nhas a key \"name\", use { \"path\": \"name\" } (NO leading slash \u2014 relative to item).\nCRITICAL: Do NOT use \"/name\" (absolute) inside templates \u2014 use \"name\" (relative).\nThe container's path (\"/items\") uses a leading slash (absolute), but all\ncomponents INSIDE the template use paths WITHOUT leading slash.\n\nDATA MODEL:\nThe \"data\" key in the tool args is a plain JSON object that initializes the surface\ndata model. Components bound to paths (e.g. \"value\": { \"path\": \"/form/name\" })\nread from and write to this data model. Examples:\n For forms: \"data\": { \"form\": { \"name\": \"Alice\", \"email\": \"\" } }\n For lists: \"data\": { \"items\": [{\"name\": \"Product A\"}, {\"name\": \"Product B\"}] }\n For mixed: \"data\": { \"form\": { \"query\": \"\" }, \"results\": [...] }\n\nFORMS AND TWO-WAY DATA BINDING:\nTo create editable forms, bind input components to data model paths using { \"path\": \"...\" }.\nThe client automatically writes user input back to the data model at the bound path.\nCRITICAL: Using a literal value (e.g. \"value\": \"\") makes the field READ-ONLY.\nYou MUST use { \"path\": \"...\" } to make inputs editable.\n\nInput components use \"value\" as the binding property:\n \"value\": { \"path\": \"/form/fieldName\" }\n\nTo retrieve form values when a button is clicked, include \"context\" with path references\nin the button's action. Paths are resolved to their current values at click time:\n \"action\": { \"event\": { \"name\": \"submit\", \"context\": { \"userName\": { \"path\": \"/form/name\" } } } }\n\nTo pre-fill form values, pass initial data via the \"data\" tool argument:\n \"data\": { \"form\": { \"name\": \"Markus\" } }";
13
+ /**
14
+ * Design guidelines — visual design rules, component hierarchy tips,
15
+ * and action handler patterns.
16
+ */
17
+ declare const A2UI_DEFAULT_DESIGN_GUIDELINES = "Create polished, visually appealing interfaces. ONLY use components listed in the\nAvailable Components schema \u2014 do NOT use component names that are not in the schema.\n\nDesign principles:\n- Create clear visual hierarchy within cards and layouts.\n- Keep cards clean \u2014 avoid clutter. Whitespace is good.\n- Use consistent surfaceIds (lowercase, hyphenated).\n- NEVER use the same ID for a component and its child \u2014 this creates a\n circular dependency. E.g. if id=\"avatar\", child must NOT be \"avatar\".\n- For side-by-side comparisons, use a container with structural children\n (children: { componentId, path }) to repeat a card template per data item.\n- Include images when relevant (logos, icons, product photos):\n - Prefer company logos via Google favicons: https://www.google.com/s2/favicons?domain=example.com&sz=128\n - Do NOT invent Unsplash photo-IDs \u2014 they will 404. Only use real, known URLs.\n- For buttons: action MUST use this exact nested format:\n \"action\": { \"event\": { \"name\": \"myAction\", \"context\": { \"key\": \"value\" } } }\n The \"event\" key holds an OBJECT with \"name\" (required) and \"context\" (optional).\n Do NOT use a flat format like {\"event\": \"name\"} \u2014 \"event\" must be an object.\n- For forms: every input MUST use path binding on the \"value\" property\n (e.g. \"value\": { \"path\": \"/form/name\" }) to be editable. The submit button's\n action context MUST reference the same paths to capture the user's input.\n\nUse the SAME surfaceId as the main surface. Match action names to button action event names.";
18
+ //#endregion
19
+ export { A2UI_DEFAULT_DESIGN_GUIDELINES, A2UI_DEFAULT_GENERATION_GUIDELINES };
20
+ //# sourceMappingURL=a2ui-prompts.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a2ui-prompts.d.cts","names":[],"sources":["../src/a2ui-prompts.ts"],"mappings":";;AAWA;;;;;AAkEA;;;;AAAA,cAlEa,kCAAA;;;;;cAkEA,8BAAA"}
@@ -0,0 +1,20 @@
1
+ //#region src/a2ui-prompts.d.ts
2
+ /**
3
+ * Default A2UI generation and design guideline prompts.
4
+ *
5
+ * These are the canonical prompt fragments that instruct an LLM how to call
6
+ * the render_a2ui tool, how to bind data, and how to style surfaces.
7
+ */
8
+ /**
9
+ * Generation guidelines — protocol rules, tool arguments, path rules,
10
+ * data model format, and form/two-way-binding instructions.
11
+ */
12
+ declare const A2UI_DEFAULT_GENERATION_GUIDELINES = "Generate A2UI v0.9 JSON.\n\n## A2UI Protocol Instructions\n\nA2UI (Agent to UI) is a protocol for rendering rich UI surfaces from agent responses.\n\nCRITICAL: You MUST call the render_a2ui tool with ALL of these arguments:\n- surfaceId: A unique ID for the surface (e.g. \"product-comparison\")\n- components: REQUIRED \u2014 the A2UI component array. NEVER omit this. Only use\n components listed in the Available Components schema provided as context.\n- data: OPTIONAL \u2014 a JSON object written to the root of the surface data model.\n Use for pre-filling form values or providing data for path-bound components.\n- every component must have the \"component\" field specifying the component type.\n ONLY use component names from the Available Components schema \u2014 do NOT invent\n component names or use names not in the schema.\n\nCOMPONENT ID RULES:\n- Every component ID must be unique within the surface.\n- A component MUST NOT reference itself as child/children. This causes a\n circular dependency error. For example, if a component has id=\"avatar\",\n its child must be a DIFFERENT id (e.g. \"avatar-img\"), never \"avatar\".\n- The child/children tree must be a DAG \u2014 no cycles allowed.\n\nREPEATING CONTENT (TEMPLATES):\nTo repeat a component for each item in an array, use the structural children format:\n children: { componentId: \"card-id\", path: \"/items\" }\nThis tells the renderer to create one instance of \"card-id\" per item in the \"/items\" array.\n\nPATH RULES FOR TEMPLATES:\nComponents inside a repeating template use RELATIVE paths (no leading slash).\nThe path is resolved relative to each array item automatically.\nIf a container has children: { componentId: \"card\", path: \"/items\" } and each item\nhas a key \"name\", use { \"path\": \"name\" } (NO leading slash \u2014 relative to item).\nCRITICAL: Do NOT use \"/name\" (absolute) inside templates \u2014 use \"name\" (relative).\nThe container's path (\"/items\") uses a leading slash (absolute), but all\ncomponents INSIDE the template use paths WITHOUT leading slash.\n\nDATA MODEL:\nThe \"data\" key in the tool args is a plain JSON object that initializes the surface\ndata model. Components bound to paths (e.g. \"value\": { \"path\": \"/form/name\" })\nread from and write to this data model. Examples:\n For forms: \"data\": { \"form\": { \"name\": \"Alice\", \"email\": \"\" } }\n For lists: \"data\": { \"items\": [{\"name\": \"Product A\"}, {\"name\": \"Product B\"}] }\n For mixed: \"data\": { \"form\": { \"query\": \"\" }, \"results\": [...] }\n\nFORMS AND TWO-WAY DATA BINDING:\nTo create editable forms, bind input components to data model paths using { \"path\": \"...\" }.\nThe client automatically writes user input back to the data model at the bound path.\nCRITICAL: Using a literal value (e.g. \"value\": \"\") makes the field READ-ONLY.\nYou MUST use { \"path\": \"...\" } to make inputs editable.\n\nInput components use \"value\" as the binding property:\n \"value\": { \"path\": \"/form/fieldName\" }\n\nTo retrieve form values when a button is clicked, include \"context\" with path references\nin the button's action. Paths are resolved to their current values at click time:\n \"action\": { \"event\": { \"name\": \"submit\", \"context\": { \"userName\": { \"path\": \"/form/name\" } } } }\n\nTo pre-fill form values, pass initial data via the \"data\" tool argument:\n \"data\": { \"form\": { \"name\": \"Markus\" } }";
13
+ /**
14
+ * Design guidelines — visual design rules, component hierarchy tips,
15
+ * and action handler patterns.
16
+ */
17
+ declare const A2UI_DEFAULT_DESIGN_GUIDELINES = "Create polished, visually appealing interfaces. ONLY use components listed in the\nAvailable Components schema \u2014 do NOT use component names that are not in the schema.\n\nDesign principles:\n- Create clear visual hierarchy within cards and layouts.\n- Keep cards clean \u2014 avoid clutter. Whitespace is good.\n- Use consistent surfaceIds (lowercase, hyphenated).\n- NEVER use the same ID for a component and its child \u2014 this creates a\n circular dependency. E.g. if id=\"avatar\", child must NOT be \"avatar\".\n- For side-by-side comparisons, use a container with structural children\n (children: { componentId, path }) to repeat a card template per data item.\n- Include images when relevant (logos, icons, product photos):\n - Prefer company logos via Google favicons: https://www.google.com/s2/favicons?domain=example.com&sz=128\n - Do NOT invent Unsplash photo-IDs \u2014 they will 404. Only use real, known URLs.\n- For buttons: action MUST use this exact nested format:\n \"action\": { \"event\": { \"name\": \"myAction\", \"context\": { \"key\": \"value\" } } }\n The \"event\" key holds an OBJECT with \"name\" (required) and \"context\" (optional).\n Do NOT use a flat format like {\"event\": \"name\"} \u2014 \"event\" must be an object.\n- For forms: every input MUST use path binding on the \"value\" property\n (e.g. \"value\": { \"path\": \"/form/name\" }) to be editable. The submit button's\n action context MUST reference the same paths to capture the user's input.\n\nUse the SAME surfaceId as the main surface. Match action names to button action event names.";
18
+ //#endregion
19
+ export { A2UI_DEFAULT_DESIGN_GUIDELINES, A2UI_DEFAULT_GENERATION_GUIDELINES };
20
+ //# sourceMappingURL=a2ui-prompts.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a2ui-prompts.d.mts","names":[],"sources":["../src/a2ui-prompts.ts"],"mappings":";;AAWA;;;;;AAkEA;;;;AAAA,cAlEa,kCAAA;;;;;cAkEA,8BAAA"}
@@ -0,0 +1,104 @@
1
+ //#region src/a2ui-prompts.ts
2
+ /**
3
+ * Default A2UI generation and design guideline prompts.
4
+ *
5
+ * These are the canonical prompt fragments that instruct an LLM how to call
6
+ * the render_a2ui tool, how to bind data, and how to style surfaces.
7
+ */
8
+ /**
9
+ * Generation guidelines — protocol rules, tool arguments, path rules,
10
+ * data model format, and form/two-way-binding instructions.
11
+ */
12
+ const A2UI_DEFAULT_GENERATION_GUIDELINES = `\
13
+ Generate A2UI v0.9 JSON.
14
+
15
+ ## A2UI Protocol Instructions
16
+
17
+ A2UI (Agent to UI) is a protocol for rendering rich UI surfaces from agent responses.
18
+
19
+ CRITICAL: You MUST call the render_a2ui tool with ALL of these arguments:
20
+ - surfaceId: A unique ID for the surface (e.g. "product-comparison")
21
+ - components: REQUIRED — the A2UI component array. NEVER omit this. Only use
22
+ components listed in the Available Components schema provided as context.
23
+ - data: OPTIONAL — a JSON object written to the root of the surface data model.
24
+ Use for pre-filling form values or providing data for path-bound components.
25
+ - every component must have the "component" field specifying the component type.
26
+ ONLY use component names from the Available Components schema — do NOT invent
27
+ component names or use names not in the schema.
28
+
29
+ COMPONENT ID RULES:
30
+ - Every component ID must be unique within the surface.
31
+ - A component MUST NOT reference itself as child/children. This causes a
32
+ circular dependency error. For example, if a component has id="avatar",
33
+ its child must be a DIFFERENT id (e.g. "avatar-img"), never "avatar".
34
+ - The child/children tree must be a DAG — no cycles allowed.
35
+
36
+ REPEATING CONTENT (TEMPLATES):
37
+ To repeat a component for each item in an array, use the structural children format:
38
+ children: { componentId: "card-id", path: "/items" }
39
+ This tells the renderer to create one instance of "card-id" per item in the "/items" array.
40
+
41
+ PATH RULES FOR TEMPLATES:
42
+ Components inside a repeating template use RELATIVE paths (no leading slash).
43
+ The path is resolved relative to each array item automatically.
44
+ If a container has children: { componentId: "card", path: "/items" } and each item
45
+ has a key "name", use { "path": "name" } (NO leading slash — relative to item).
46
+ CRITICAL: Do NOT use "/name" (absolute) inside templates — use "name" (relative).
47
+ The container's path ("/items") uses a leading slash (absolute), but all
48
+ components INSIDE the template use paths WITHOUT leading slash.
49
+
50
+ DATA MODEL:
51
+ The "data" key in the tool args is a plain JSON object that initializes the surface
52
+ data model. Components bound to paths (e.g. "value": { "path": "/form/name" })
53
+ read from and write to this data model. Examples:
54
+ For forms: "data": { "form": { "name": "Alice", "email": "" } }
55
+ For lists: "data": { "items": [{"name": "Product A"}, {"name": "Product B"}] }
56
+ For mixed: "data": { "form": { "query": "" }, "results": [...] }
57
+
58
+ FORMS AND TWO-WAY DATA BINDING:
59
+ To create editable forms, bind input components to data model paths using { "path": "..." }.
60
+ The client automatically writes user input back to the data model at the bound path.
61
+ CRITICAL: Using a literal value (e.g. "value": "") makes the field READ-ONLY.
62
+ You MUST use { "path": "..." } to make inputs editable.
63
+
64
+ Input components use "value" as the binding property:
65
+ "value": { "path": "/form/fieldName" }
66
+
67
+ To retrieve form values when a button is clicked, include "context" with path references
68
+ in the button's action. Paths are resolved to their current values at click time:
69
+ "action": { "event": { "name": "submit", "context": { "userName": { "path": "/form/name" } } } }
70
+
71
+ To pre-fill form values, pass initial data via the "data" tool argument:
72
+ "data": { "form": { "name": "Markus" } }`;
73
+ /**
74
+ * Design guidelines — visual design rules, component hierarchy tips,
75
+ * and action handler patterns.
76
+ */
77
+ const A2UI_DEFAULT_DESIGN_GUIDELINES = `\
78
+ Create polished, visually appealing interfaces. ONLY use components listed in the
79
+ Available Components schema — do NOT use component names that are not in the schema.
80
+
81
+ Design principles:
82
+ - Create clear visual hierarchy within cards and layouts.
83
+ - Keep cards clean — avoid clutter. Whitespace is good.
84
+ - Use consistent surfaceIds (lowercase, hyphenated).
85
+ - NEVER use the same ID for a component and its child — this creates a
86
+ circular dependency. E.g. if id="avatar", child must NOT be "avatar".
87
+ - For side-by-side comparisons, use a container with structural children
88
+ (children: { componentId, path }) to repeat a card template per data item.
89
+ - Include images when relevant (logos, icons, product photos):
90
+ - Prefer company logos via Google favicons: https://www.google.com/s2/favicons?domain=example.com&sz=128
91
+ - Do NOT invent Unsplash photo-IDs — they will 404. Only use real, known URLs.
92
+ - For buttons: action MUST use this exact nested format:
93
+ "action": { "event": { "name": "myAction", "context": { "key": "value" } } }
94
+ The "event" key holds an OBJECT with "name" (required) and "context" (optional).
95
+ Do NOT use a flat format like {"event": "name"} — "event" must be an object.
96
+ - For forms: every input MUST use path binding on the "value" property
97
+ (e.g. "value": { "path": "/form/name" }) to be editable. The submit button's
98
+ action context MUST reference the same paths to capture the user's input.
99
+
100
+ Use the SAME surfaceId as the main surface. Match action names to button action event names.`;
101
+
102
+ //#endregion
103
+ export { A2UI_DEFAULT_DESIGN_GUIDELINES, A2UI_DEFAULT_GENERATION_GUIDELINES };
104
+ //# sourceMappingURL=a2ui-prompts.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a2ui-prompts.mjs","names":[],"sources":["../src/a2ui-prompts.ts"],"sourcesContent":["/**\n * Default A2UI generation and design guideline prompts.\n *\n * These are the canonical prompt fragments that instruct an LLM how to call\n * the render_a2ui tool, how to bind data, and how to style surfaces.\n */\n\n/**\n * Generation guidelines — protocol rules, tool arguments, path rules,\n * data model format, and form/two-way-binding instructions.\n */\nexport const A2UI_DEFAULT_GENERATION_GUIDELINES = `\\\nGenerate A2UI v0.9 JSON.\n\n## A2UI Protocol Instructions\n\nA2UI (Agent to UI) is a protocol for rendering rich UI surfaces from agent responses.\n\nCRITICAL: You MUST call the render_a2ui tool with ALL of these arguments:\n- surfaceId: A unique ID for the surface (e.g. \"product-comparison\")\n- components: REQUIRED — the A2UI component array. NEVER omit this. Only use\n components listed in the Available Components schema provided as context.\n- data: OPTIONAL — a JSON object written to the root of the surface data model.\n Use for pre-filling form values or providing data for path-bound components.\n- every component must have the \"component\" field specifying the component type.\n ONLY use component names from the Available Components schema — do NOT invent\n component names or use names not in the schema.\n\nCOMPONENT ID RULES:\n- Every component ID must be unique within the surface.\n- A component MUST NOT reference itself as child/children. This causes a\n circular dependency error. For example, if a component has id=\"avatar\",\n its child must be a DIFFERENT id (e.g. \"avatar-img\"), never \"avatar\".\n- The child/children tree must be a DAG — no cycles allowed.\n\nREPEATING CONTENT (TEMPLATES):\nTo repeat a component for each item in an array, use the structural children format:\n children: { componentId: \"card-id\", path: \"/items\" }\nThis tells the renderer to create one instance of \"card-id\" per item in the \"/items\" array.\n\nPATH RULES FOR TEMPLATES:\nComponents inside a repeating template use RELATIVE paths (no leading slash).\nThe path is resolved relative to each array item automatically.\nIf a container has children: { componentId: \"card\", path: \"/items\" } and each item\nhas a key \"name\", use { \"path\": \"name\" } (NO leading slash — relative to item).\nCRITICAL: Do NOT use \"/name\" (absolute) inside templates — use \"name\" (relative).\nThe container's path (\"/items\") uses a leading slash (absolute), but all\ncomponents INSIDE the template use paths WITHOUT leading slash.\n\nDATA MODEL:\nThe \"data\" key in the tool args is a plain JSON object that initializes the surface\ndata model. Components bound to paths (e.g. \"value\": { \"path\": \"/form/name\" })\nread from and write to this data model. Examples:\n For forms: \"data\": { \"form\": { \"name\": \"Alice\", \"email\": \"\" } }\n For lists: \"data\": { \"items\": [{\"name\": \"Product A\"}, {\"name\": \"Product B\"}] }\n For mixed: \"data\": { \"form\": { \"query\": \"\" }, \"results\": [...] }\n\nFORMS AND TWO-WAY DATA BINDING:\nTo create editable forms, bind input components to data model paths using { \"path\": \"...\" }.\nThe client automatically writes user input back to the data model at the bound path.\nCRITICAL: Using a literal value (e.g. \"value\": \"\") makes the field READ-ONLY.\nYou MUST use { \"path\": \"...\" } to make inputs editable.\n\nInput components use \"value\" as the binding property:\n \"value\": { \"path\": \"/form/fieldName\" }\n\nTo retrieve form values when a button is clicked, include \"context\" with path references\nin the button's action. Paths are resolved to their current values at click time:\n \"action\": { \"event\": { \"name\": \"submit\", \"context\": { \"userName\": { \"path\": \"/form/name\" } } } }\n\nTo pre-fill form values, pass initial data via the \"data\" tool argument:\n \"data\": { \"form\": { \"name\": \"Markus\" } }`;\n\n/**\n * Design guidelines — visual design rules, component hierarchy tips,\n * and action handler patterns.\n */\nexport const A2UI_DEFAULT_DESIGN_GUIDELINES = `\\\nCreate polished, visually appealing interfaces. ONLY use components listed in the\nAvailable Components schema — do NOT use component names that are not in the schema.\n\nDesign principles:\n- Create clear visual hierarchy within cards and layouts.\n- Keep cards clean — avoid clutter. Whitespace is good.\n- Use consistent surfaceIds (lowercase, hyphenated).\n- NEVER use the same ID for a component and its child — this creates a\n circular dependency. E.g. if id=\"avatar\", child must NOT be \"avatar\".\n- For side-by-side comparisons, use a container with structural children\n (children: { componentId, path }) to repeat a card template per data item.\n- Include images when relevant (logos, icons, product photos):\n - Prefer company logos via Google favicons: https://www.google.com/s2/favicons?domain=example.com&sz=128\n - Do NOT invent Unsplash photo-IDs — they will 404. Only use real, known URLs.\n- For buttons: action MUST use this exact nested format:\n \"action\": { \"event\": { \"name\": \"myAction\", \"context\": { \"key\": \"value\" } } }\n The \"event\" key holds an OBJECT with \"name\" (required) and \"context\" (optional).\n Do NOT use a flat format like {\"event\": \"name\"} — \"event\" must be an object.\n- For forms: every input MUST use path binding on the \"value\" property\n (e.g. \"value\": { \"path\": \"/form/name\" }) to be editable. The submit button's\n action context MUST reference the same paths to capture the user's input.\n\nUse the SAME surfaceId as the main surface. Match action names to button action event names.`;\n"],"mappings":";;;;;;;;;;;AAWA,MAAa,qCAAqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkElD,MAAa,iCAAiC"}
@@ -0,0 +1,54 @@
1
+ import { InputContentDataSource, InputContentUrlSource } from "@ag-ui/core";
2
+
3
+ //#region src/attachments/types.d.ts
4
+ interface AttachmentUploadDataResult {
5
+ type: "data";
6
+ value: string;
7
+ mimeType: string;
8
+ /** Custom metadata to include in the InputContent part (merged with auto-generated metadata like filename). */
9
+ metadata?: Record<string, unknown>;
10
+ }
11
+ interface AttachmentUploadUrlResult {
12
+ type: "url";
13
+ value: string;
14
+ mimeType?: string;
15
+ /** Custom metadata to include in the InputContent part (merged with auto-generated metadata like filename). */
16
+ metadata?: Record<string, unknown>;
17
+ }
18
+ type AttachmentUploadResult = AttachmentUploadDataResult | AttachmentUploadUrlResult;
19
+ type AttachmentUploadErrorReason = "file-too-large" | "invalid-type" | "upload-failed";
20
+ interface AttachmentUploadError {
21
+ /** Why the upload failed. */
22
+ reason: AttachmentUploadErrorReason;
23
+ /** The file that failed to upload. */
24
+ file: File;
25
+ /** Human-readable error message. */
26
+ message: string;
27
+ }
28
+ interface AttachmentsConfig {
29
+ /** Enable file attachments in the chat input */
30
+ enabled: boolean;
31
+ /** MIME type filter for the file input, default all files */
32
+ accept?: string;
33
+ /** Maximum file size in bytes, default 20MB (20 * 1024 * 1024) */
34
+ maxSize?: number;
35
+ /** Custom upload handler. Return an InputContentSource with optional metadata. */
36
+ onUpload?: (file: File) => AttachmentUploadResult | Promise<AttachmentUploadResult>;
37
+ /** Called when an attachment fails validation or upload. Use this to show a toast or inline error. */
38
+ onUploadFailed?: (error: AttachmentUploadError) => void;
39
+ }
40
+ type AttachmentModality = "image" | "audio" | "video" | "document";
41
+ interface Attachment {
42
+ id: string;
43
+ type: AttachmentModality;
44
+ source: InputContentDataSource | InputContentUrlSource;
45
+ filename?: string;
46
+ size?: number;
47
+ status: "uploading" | "ready";
48
+ thumbnail?: string;
49
+ /** Custom metadata from onUpload, included in the InputContent part. */
50
+ metadata?: Record<string, unknown>;
51
+ }
52
+ //#endregion
53
+ export { Attachment, AttachmentModality, AttachmentUploadError, AttachmentUploadErrorReason, AttachmentUploadResult, AttachmentsConfig };
54
+ //# sourceMappingURL=types.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.cts","names":[],"sources":["../../src/attachments/types.ts"],"mappings":";;;UAKiB,0BAAA;EACf,IAAA;EACA,KAAA;EACA,QAAA;;EAEA,QAAA,GAAW,MAAA;AAAA;AAAA,UAGI,yBAAA;EACf,IAAA;EACA,KAAA;EACA,QAAA;EANiB;EAQjB,QAAA,GAAW,MAAA;AAAA;AAAA,KAGD,sBAAA,GACR,0BAAA,GACA,yBAAA;AAAA,KAEQ,2BAAA;AAAA,UAKK,qBAAA;EAhBf;EAkBA,MAAA,EAAQ,2BAAA;EAhBR;EAkBA,IAAA,EAAM,IAAA;EAhBK;EAkBX,OAAA;AAAA;AAAA,UAGe,iBAAA;EAlBiB;EAoBhC,OAAA;EAnBE;EAqBF,MAAA;EAlBU;EAoBV,OAAA;;EAEA,QAAA,IACE,IAAA,EAAM,IAAA,KACH,sBAAA,GAAyB,OAAA,CAAQ,sBAAA;EAxBD;EA0BrC,cAAA,IAAkB,KAAA,EAAO,qBAAA;AAAA;AAAA,KAGf,kBAAA;AAAA,UAEK,UAAA;EACf,EAAA;EACA,IAAA,EAAM,kBAAA;EACN,MAAA,EAAQ,sBAAA,GAAyB,qBAAA;EACjC,QAAA;EACA,IAAA;EACA,MAAA;EACA,SAAA;EAxBe;EA0Bf,QAAA,GAAW,MAAA;AAAA"}
@@ -0,0 +1,54 @@
1
+ import { InputContentDataSource, InputContentUrlSource } from "@ag-ui/core";
2
+
3
+ //#region src/attachments/types.d.ts
4
+ interface AttachmentUploadDataResult {
5
+ type: "data";
6
+ value: string;
7
+ mimeType: string;
8
+ /** Custom metadata to include in the InputContent part (merged with auto-generated metadata like filename). */
9
+ metadata?: Record<string, unknown>;
10
+ }
11
+ interface AttachmentUploadUrlResult {
12
+ type: "url";
13
+ value: string;
14
+ mimeType?: string;
15
+ /** Custom metadata to include in the InputContent part (merged with auto-generated metadata like filename). */
16
+ metadata?: Record<string, unknown>;
17
+ }
18
+ type AttachmentUploadResult = AttachmentUploadDataResult | AttachmentUploadUrlResult;
19
+ type AttachmentUploadErrorReason = "file-too-large" | "invalid-type" | "upload-failed";
20
+ interface AttachmentUploadError {
21
+ /** Why the upload failed. */
22
+ reason: AttachmentUploadErrorReason;
23
+ /** The file that failed to upload. */
24
+ file: File;
25
+ /** Human-readable error message. */
26
+ message: string;
27
+ }
28
+ interface AttachmentsConfig {
29
+ /** Enable file attachments in the chat input */
30
+ enabled: boolean;
31
+ /** MIME type filter for the file input, default all files */
32
+ accept?: string;
33
+ /** Maximum file size in bytes, default 20MB (20 * 1024 * 1024) */
34
+ maxSize?: number;
35
+ /** Custom upload handler. Return an InputContentSource with optional metadata. */
36
+ onUpload?: (file: File) => AttachmentUploadResult | Promise<AttachmentUploadResult>;
37
+ /** Called when an attachment fails validation or upload. Use this to show a toast or inline error. */
38
+ onUploadFailed?: (error: AttachmentUploadError) => void;
39
+ }
40
+ type AttachmentModality = "image" | "audio" | "video" | "document";
41
+ interface Attachment {
42
+ id: string;
43
+ type: AttachmentModality;
44
+ source: InputContentDataSource | InputContentUrlSource;
45
+ filename?: string;
46
+ size?: number;
47
+ status: "uploading" | "ready";
48
+ thumbnail?: string;
49
+ /** Custom metadata from onUpload, included in the InputContent part. */
50
+ metadata?: Record<string, unknown>;
51
+ }
52
+ //#endregion
53
+ export { Attachment, AttachmentModality, AttachmentUploadError, AttachmentUploadErrorReason, AttachmentUploadResult, AttachmentsConfig };
54
+ //# sourceMappingURL=types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../../src/attachments/types.ts"],"mappings":";;;UAKiB,0BAAA;EACf,IAAA;EACA,KAAA;EACA,QAAA;;EAEA,QAAA,GAAW,MAAA;AAAA;AAAA,UAGI,yBAAA;EACf,IAAA;EACA,KAAA;EACA,QAAA;EANiB;EAQjB,QAAA,GAAW,MAAA;AAAA;AAAA,KAGD,sBAAA,GACR,0BAAA,GACA,yBAAA;AAAA,KAEQ,2BAAA;AAAA,UAKK,qBAAA;EAhBf;EAkBA,MAAA,EAAQ,2BAAA;EAhBR;EAkBA,IAAA,EAAM,IAAA;EAhBK;EAkBX,OAAA;AAAA;AAAA,UAGe,iBAAA;EAlBiB;EAoBhC,OAAA;EAnBE;EAqBF,MAAA;EAlBU;EAoBV,OAAA;;EAEA,QAAA,IACE,IAAA,EAAM,IAAA,KACH,sBAAA,GAAyB,OAAA,CAAQ,sBAAA;EAxBD;EA0BrC,cAAA,IAAkB,KAAA,EAAO,qBAAA;AAAA;AAAA,KAGf,kBAAA;AAAA,UAEK,UAAA;EACf,EAAA;EACA,IAAA,EAAM,kBAAA;EACN,MAAA,EAAQ,sBAAA,GAAyB,qBAAA;EACjC,QAAA;EACA,IAAA;EACA,MAAA;EACA,SAAA;EAxBe;EA0Bf,QAAA,GAAW,MAAA;AAAA"}
@@ -0,0 +1,134 @@
1
+
2
+ //#region src/attachments/utils.ts
3
+ const DEFAULT_MAX_SIZE = 20 * 1024 * 1024;
4
+ /**
5
+ * Derive the attachment modality from a MIME type string.
6
+ */
7
+ function getModalityFromMimeType(mimeType) {
8
+ if (mimeType.startsWith("image/")) return "image";
9
+ if (mimeType.startsWith("audio/")) return "audio";
10
+ if (mimeType.startsWith("video/")) return "video";
11
+ return "document";
12
+ }
13
+ /**
14
+ * Format a byte count as a human-readable file size string.
15
+ */
16
+ function formatFileSize(bytes) {
17
+ if (bytes < 1024) return `${bytes} B`;
18
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
19
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
20
+ }
21
+ /**
22
+ * Check if a file exceeds the maximum allowed size.
23
+ */
24
+ function exceedsMaxSize(file, maxSize = DEFAULT_MAX_SIZE) {
25
+ return file.size > maxSize;
26
+ }
27
+ /**
28
+ * Read a File as a base64 string (without the data URL prefix).
29
+ */
30
+ function readFileAsBase64(file) {
31
+ return new Promise((resolve, reject) => {
32
+ const reader = new FileReader();
33
+ reader.onload = (e) => {
34
+ const base64 = (e.target?.result)?.split(",")[1];
35
+ if (base64) resolve(base64);
36
+ else reject(/* @__PURE__ */ new Error("Failed to read file as base64"));
37
+ };
38
+ reader.onerror = reject;
39
+ reader.readAsDataURL(file);
40
+ });
41
+ }
42
+ /**
43
+ * Generate a thumbnail data URL from a video file by capturing a frame near the start (at 0.1s).
44
+ * Returns undefined if thumbnail generation fails or if called outside a browser environment.
45
+ */
46
+ function generateVideoThumbnail(file) {
47
+ if (typeof document === "undefined") return Promise.resolve(void 0);
48
+ return new Promise((resolve) => {
49
+ let resolved = false;
50
+ const video = document.createElement("video");
51
+ const canvas = document.createElement("canvas");
52
+ const url = URL.createObjectURL(file);
53
+ const cleanup = (result) => {
54
+ if (resolved) return;
55
+ resolved = true;
56
+ URL.revokeObjectURL(url);
57
+ resolve(result);
58
+ };
59
+ const timeout = setTimeout(() => {
60
+ console.warn(`[CopilotKit] generateVideoThumbnail: timed out for file "${file.name}"`);
61
+ cleanup(void 0);
62
+ }, 1e4);
63
+ video.preload = "metadata";
64
+ video.muted = true;
65
+ video.playsInline = true;
66
+ video.onloadeddata = () => {
67
+ video.currentTime = .1;
68
+ };
69
+ video.onseeked = () => {
70
+ clearTimeout(timeout);
71
+ canvas.width = video.videoWidth;
72
+ canvas.height = video.videoHeight;
73
+ const ctx = canvas.getContext("2d");
74
+ if (ctx) {
75
+ ctx.drawImage(video, 0, 0);
76
+ cleanup(canvas.toDataURL("image/jpeg", .7));
77
+ } else {
78
+ console.warn("[CopilotKit] generateVideoThumbnail: could not get 2d canvas context");
79
+ cleanup(void 0);
80
+ }
81
+ };
82
+ video.onerror = () => {
83
+ clearTimeout(timeout);
84
+ console.warn(`[CopilotKit] generateVideoThumbnail: video element error for file "${file.name}"`);
85
+ cleanup(void 0);
86
+ };
87
+ video.src = url;
88
+ });
89
+ }
90
+ /**
91
+ * Check if a file's MIME type matches an accept filter string.
92
+ * Handles file extensions (e.g. ".pdf"), MIME wildcards ("image/*"), and comma-separated lists.
93
+ */
94
+ function matchesAcceptFilter(file, accept) {
95
+ if (!accept || accept === "*/*") return true;
96
+ return accept.split(",").map((f) => f.trim()).some((filter) => {
97
+ if (filter.startsWith(".")) return (file.name ?? "").toLowerCase().endsWith(filter.toLowerCase());
98
+ if (filter.endsWith("/*")) {
99
+ const prefix = filter.slice(0, -2);
100
+ return file.type.startsWith(prefix + "/");
101
+ }
102
+ return file.type === filter;
103
+ });
104
+ }
105
+ /**
106
+ * Convert an InputContentSource to a usable URL string.
107
+ * For data sources, returns a base64 data URL; for URL sources, returns the URL directly.
108
+ */
109
+ function getSourceUrl(source) {
110
+ if (source.type === "url") return source.value;
111
+ return `data:${source.mimeType};base64,${source.value}`;
112
+ }
113
+ /**
114
+ * Return a short human-readable label for a document MIME type (e.g. "PDF", "DOC").
115
+ */
116
+ function getDocumentIcon(mimeType) {
117
+ if (mimeType.includes("pdf")) return "PDF";
118
+ if (mimeType.includes("sheet") || mimeType.includes("excel")) return "XLS";
119
+ if (mimeType.includes("presentation") || mimeType.includes("powerpoint")) return "PPT";
120
+ if (mimeType.includes("word") || mimeType.includes("document")) return "DOC";
121
+ if (mimeType.includes("text/")) return "TXT";
122
+ return "FILE";
123
+ }
124
+
125
+ //#endregion
126
+ exports.exceedsMaxSize = exceedsMaxSize;
127
+ exports.formatFileSize = formatFileSize;
128
+ exports.generateVideoThumbnail = generateVideoThumbnail;
129
+ exports.getDocumentIcon = getDocumentIcon;
130
+ exports.getModalityFromMimeType = getModalityFromMimeType;
131
+ exports.getSourceUrl = getSourceUrl;
132
+ exports.matchesAcceptFilter = matchesAcceptFilter;
133
+ exports.readFileAsBase64 = readFileAsBase64;
134
+ //# sourceMappingURL=utils.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.cjs","names":[],"sources":["../../src/attachments/utils.ts"],"sourcesContent":["import type { AttachmentModality } from \"./types\";\nimport type { InputContentSource } from \"../types/message\";\n\nconst DEFAULT_MAX_SIZE = 20 * 1024 * 1024; // 20MB\n\n/**\n * Derive the attachment modality from a MIME type string.\n */\nexport function getModalityFromMimeType(mimeType: string): AttachmentModality {\n if (mimeType.startsWith(\"image/\")) return \"image\";\n if (mimeType.startsWith(\"audio/\")) return \"audio\";\n if (mimeType.startsWith(\"video/\")) return \"video\";\n return \"document\";\n}\n\n/**\n * Format a byte count as a human-readable file size string.\n */\nexport function formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\n/**\n * Check if a file exceeds the maximum allowed size.\n */\nexport function exceedsMaxSize(\n file: File,\n maxSize: number = DEFAULT_MAX_SIZE,\n): boolean {\n return file.size > maxSize;\n}\n\n/**\n * Read a File as a base64 string (without the data URL prefix).\n */\nexport function readFileAsBase64(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = (e) => {\n const result = e.target?.result as string;\n const base64 = result?.split(\",\")[1];\n if (base64) {\n resolve(base64);\n } else {\n reject(new Error(\"Failed to read file as base64\"));\n }\n };\n reader.onerror = reject;\n reader.readAsDataURL(file);\n });\n}\n\n/**\n * Generate a thumbnail data URL from a video file by capturing a frame near the start (at 0.1s).\n * Returns undefined if thumbnail generation fails or if called outside a browser environment.\n */\nexport function generateVideoThumbnail(\n file: File,\n): Promise<string | undefined> {\n if (typeof document === \"undefined\") {\n return Promise.resolve(undefined);\n }\n return new Promise((resolve) => {\n let resolved = false;\n const video = document.createElement(\"video\");\n const canvas = document.createElement(\"canvas\");\n const url = URL.createObjectURL(file);\n\n const cleanup = (result: string | undefined) => {\n if (resolved) return;\n resolved = true;\n URL.revokeObjectURL(url);\n resolve(result);\n };\n\n const timeout = setTimeout(() => {\n console.warn(\n `[CopilotKit] generateVideoThumbnail: timed out for file \"${file.name}\"`,\n );\n cleanup(undefined);\n }, 10000);\n\n video.preload = \"metadata\";\n video.muted = true;\n video.playsInline = true;\n\n video.onloadeddata = () => {\n video.currentTime = 0.1;\n };\n\n video.onseeked = () => {\n clearTimeout(timeout);\n canvas.width = video.videoWidth;\n canvas.height = video.videoHeight;\n const ctx = canvas.getContext(\"2d\");\n if (ctx) {\n ctx.drawImage(video, 0, 0);\n const thumbnail = canvas.toDataURL(\"image/jpeg\", 0.7);\n cleanup(thumbnail);\n } else {\n console.warn(\n \"[CopilotKit] generateVideoThumbnail: could not get 2d canvas context\",\n );\n cleanup(undefined);\n }\n };\n\n video.onerror = () => {\n clearTimeout(timeout);\n console.warn(\n `[CopilotKit] generateVideoThumbnail: video element error for file \"${file.name}\"`,\n );\n cleanup(undefined);\n };\n\n video.src = url;\n });\n}\n\n/**\n * Check if a file's MIME type matches an accept filter string.\n * Handles file extensions (e.g. \".pdf\"), MIME wildcards (\"image/*\"), and comma-separated lists.\n */\nexport function matchesAcceptFilter(file: File, accept: string): boolean {\n if (!accept || accept === \"*/*\") return true;\n\n const filters = accept.split(\",\").map((f) => f.trim());\n return filters.some((filter) => {\n if (filter.startsWith(\".\")) {\n return (file.name ?? \"\").toLowerCase().endsWith(filter.toLowerCase());\n }\n if (filter.endsWith(\"/*\")) {\n const prefix = filter.slice(0, -2);\n return file.type.startsWith(prefix + \"/\");\n }\n return file.type === filter;\n });\n}\n\n/**\n * Convert an InputContentSource to a usable URL string.\n * For data sources, returns a base64 data URL; for URL sources, returns the URL directly.\n */\nexport function getSourceUrl(source: InputContentSource): string {\n if (source.type === \"url\") {\n return source.value;\n }\n return `data:${source.mimeType};base64,${source.value}`;\n}\n\n/**\n * Return a short human-readable label for a document MIME type (e.g. \"PDF\", \"DOC\").\n */\nexport function getDocumentIcon(mimeType: string): string {\n if (mimeType.includes(\"pdf\")) return \"PDF\";\n if (mimeType.includes(\"sheet\") || mimeType.includes(\"excel\")) return \"XLS\";\n if (mimeType.includes(\"presentation\") || mimeType.includes(\"powerpoint\"))\n return \"PPT\";\n if (mimeType.includes(\"word\") || mimeType.includes(\"document\")) return \"DOC\";\n if (mimeType.includes(\"text/\")) return \"TXT\";\n return \"FILE\";\n}\n"],"mappings":";;AAGA,MAAM,mBAAmB,KAAK,OAAO;;;;AAKrC,SAAgB,wBAAwB,UAAsC;AAC5E,KAAI,SAAS,WAAW,SAAS,CAAE,QAAO;AAC1C,KAAI,SAAS,WAAW,SAAS,CAAE,QAAO;AAC1C,KAAI,SAAS,WAAW,SAAS,CAAE,QAAO;AAC1C,QAAO;;;;;AAMT,SAAgB,eAAe,OAAuB;AACpD,KAAI,QAAQ,KAAM,QAAO,GAAG,MAAM;AAClC,KAAI,QAAQ,OAAO,KAAM,QAAO,IAAI,QAAQ,MAAM,QAAQ,EAAE,CAAC;AAC7D,QAAO,IAAI,SAAS,OAAO,OAAO,QAAQ,EAAE,CAAC;;;;;AAM/C,SAAgB,eACd,MACA,UAAkB,kBACT;AACT,QAAO,KAAK,OAAO;;;;;AAMrB,SAAgB,iBAAiB,MAA6B;AAC5D,QAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,SAAS,IAAI,YAAY;AAC/B,SAAO,UAAU,MAAM;GAErB,MAAM,UADS,EAAE,QAAQ,SACF,MAAM,IAAI,CAAC;AAClC,OAAI,OACF,SAAQ,OAAO;OAEf,wBAAO,IAAI,MAAM,gCAAgC,CAAC;;AAGtD,SAAO,UAAU;AACjB,SAAO,cAAc,KAAK;GAC1B;;;;;;AAOJ,SAAgB,uBACd,MAC6B;AAC7B,KAAI,OAAO,aAAa,YACtB,QAAO,QAAQ,QAAQ,OAAU;AAEnC,QAAO,IAAI,SAAS,YAAY;EAC9B,IAAI,WAAW;EACf,MAAM,QAAQ,SAAS,cAAc,QAAQ;EAC7C,MAAM,SAAS,SAAS,cAAc,SAAS;EAC/C,MAAM,MAAM,IAAI,gBAAgB,KAAK;EAErC,MAAM,WAAW,WAA+B;AAC9C,OAAI,SAAU;AACd,cAAW;AACX,OAAI,gBAAgB,IAAI;AACxB,WAAQ,OAAO;;EAGjB,MAAM,UAAU,iBAAiB;AAC/B,WAAQ,KACN,4DAA4D,KAAK,KAAK,GACvE;AACD,WAAQ,OAAU;KACjB,IAAM;AAET,QAAM,UAAU;AAChB,QAAM,QAAQ;AACd,QAAM,cAAc;AAEpB,QAAM,qBAAqB;AACzB,SAAM,cAAc;;AAGtB,QAAM,iBAAiB;AACrB,gBAAa,QAAQ;AACrB,UAAO,QAAQ,MAAM;AACrB,UAAO,SAAS,MAAM;GACtB,MAAM,MAAM,OAAO,WAAW,KAAK;AACnC,OAAI,KAAK;AACP,QAAI,UAAU,OAAO,GAAG,EAAE;AAE1B,YADkB,OAAO,UAAU,cAAc,GAAI,CACnC;UACb;AACL,YAAQ,KACN,uEACD;AACD,YAAQ,OAAU;;;AAItB,QAAM,gBAAgB;AACpB,gBAAa,QAAQ;AACrB,WAAQ,KACN,sEAAsE,KAAK,KAAK,GACjF;AACD,WAAQ,OAAU;;AAGpB,QAAM,MAAM;GACZ;;;;;;AAOJ,SAAgB,oBAAoB,MAAY,QAAyB;AACvE,KAAI,CAAC,UAAU,WAAW,MAAO,QAAO;AAGxC,QADgB,OAAO,MAAM,IAAI,CAAC,KAAK,MAAM,EAAE,MAAM,CAAC,CACvC,MAAM,WAAW;AAC9B,MAAI,OAAO,WAAW,IAAI,CACxB,SAAQ,KAAK,QAAQ,IAAI,aAAa,CAAC,SAAS,OAAO,aAAa,CAAC;AAEvE,MAAI,OAAO,SAAS,KAAK,EAAE;GACzB,MAAM,SAAS,OAAO,MAAM,GAAG,GAAG;AAClC,UAAO,KAAK,KAAK,WAAW,SAAS,IAAI;;AAE3C,SAAO,KAAK,SAAS;GACrB;;;;;;AAOJ,SAAgB,aAAa,QAAoC;AAC/D,KAAI,OAAO,SAAS,MAClB,QAAO,OAAO;AAEhB,QAAO,QAAQ,OAAO,SAAS,UAAU,OAAO;;;;;AAMlD,SAAgB,gBAAgB,UAA0B;AACxD,KAAI,SAAS,SAAS,MAAM,CAAE,QAAO;AACrC,KAAI,SAAS,SAAS,QAAQ,IAAI,SAAS,SAAS,QAAQ,CAAE,QAAO;AACrE,KAAI,SAAS,SAAS,eAAe,IAAI,SAAS,SAAS,aAAa,CACtE,QAAO;AACT,KAAI,SAAS,SAAS,OAAO,IAAI,SAAS,SAAS,WAAW,CAAE,QAAO;AACvE,KAAI,SAAS,SAAS,QAAQ,CAAE,QAAO;AACvC,QAAO"}