@blokkli/editor 2.0.0-alpha.36 → 2.0.0-alpha.37

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 (218) hide show
  1. package/dist/global/types/blockOptions.d.ts +4 -3
  2. package/dist/module.d.mts +2 -2
  3. package/dist/module.json +1 -1
  4. package/dist/module.mjs +71 -4
  5. package/dist/modules/agent/index.d.mts +1 -1
  6. package/dist/modules/agent/index.mjs +236 -6
  7. package/dist/modules/agent/runtime/app/composables/agentProvider.js +31 -14
  8. package/dist/modules/agent/runtime/app/composables/defineBlokkliAgentTool.d.ts +2 -20
  9. package/dist/modules/agent/runtime/app/composables/defineBlokkliAgentTool.js +0 -3
  10. package/dist/modules/agent/runtime/app/features/agent/Panel/Conversation/Item/Assistant/index.vue +2 -2
  11. package/dist/modules/agent/runtime/app/features/agent/Panel/Conversation/Item/User/index.vue +1 -2
  12. package/dist/modules/agent/runtime/app/features/agent/Panel/DebugGallery/index.vue +1 -2
  13. package/dist/modules/agent/runtime/app/features/agent/Panel/Input/Actions/index.d.vue.ts +1 -0
  14. package/dist/modules/agent/runtime/app/features/agent/Panel/Input/Actions/index.vue +66 -59
  15. package/dist/modules/agent/runtime/app/features/agent/Panel/Input/Actions/index.vue.d.ts +1 -0
  16. package/dist/modules/agent/runtime/app/features/agent/Panel/Input/index.vue +10 -12
  17. package/dist/modules/agent/runtime/app/features/agent/Panel/Welcome/de.md +2 -2
  18. package/dist/modules/agent/runtime/app/features/agent/Panel/Welcome/en.md +2 -2
  19. package/dist/modules/agent/runtime/app/features/agent/Panel/index.vue +1 -5
  20. package/dist/modules/agent/runtime/app/features/agent/index.vue +89 -37
  21. package/dist/modules/agent/runtime/app/helpers/index.d.ts +16 -19
  22. package/dist/modules/agent/runtime/app/helpers/index.js +22 -46
  23. package/dist/modules/agent/runtime/app/helpers/pageStructure.js +1 -1
  24. package/dist/modules/agent/runtime/app/tools/add_content_search_paragraph/index.js +5 -9
  25. package/dist/modules/agent/runtime/app/tools/add_fragment/index.js +2 -6
  26. package/dist/modules/agent/runtime/app/tools/add_media_paragraph/index.js +2 -6
  27. package/dist/modules/agent/runtime/app/tools/add_paragraphs/index.js +2 -3
  28. package/dist/modules/agent/runtime/app/tools/add_reusable_paragraph/index.js +2 -6
  29. package/dist/modules/agent/runtime/app/tools/add_template/index.js +2 -6
  30. package/dist/modules/agent/runtime/app/tools/analyze_content/index.d.ts +2 -0
  31. package/dist/modules/agent/runtime/app/tools/analyze_content/index.js +120 -0
  32. package/dist/modules/agent/runtime/app/tools/check_readability/index.d.ts +2 -0
  33. package/dist/modules/agent/runtime/app/tools/check_readability/index.js +57 -0
  34. package/dist/modules/agent/runtime/app/tools/duplicate_paragraphs/index.js +2 -6
  35. package/dist/modules/agent/runtime/app/tools/get_all_page_content/index.js +1 -1
  36. package/dist/modules/agent/runtime/app/tools/get_bundle_info/index.js +2 -1
  37. package/dist/modules/agent/runtime/app/tools/get_content_fields/index.js +1 -1
  38. package/dist/modules/agent/runtime/app/tools/get_paragraph_context/index.js +2 -5
  39. package/dist/modules/agent/runtime/app/tools/get_paragraph_options/index.js +2 -1
  40. package/dist/modules/agent/runtime/app/tools/get_selected_paragraphs/index.js +2 -3
  41. package/dist/modules/agent/runtime/app/tools/helpers.d.ts +53 -0
  42. package/dist/modules/agent/runtime/app/tools/helpers.js +187 -0
  43. package/dist/modules/agent/runtime/app/tools/move_paragraphs/index.js +2 -6
  44. package/dist/modules/agent/runtime/app/tools/schemas.d.ts +0 -52
  45. package/dist/modules/agent/runtime/app/tools/schemas.js +0 -187
  46. package/dist/modules/agent/runtime/app/tools/search_content/index.js +40 -47
  47. package/dist/modules/agent/runtime/app/tools/set_paragraph_options/index.js +2 -5
  48. package/dist/modules/agent/runtime/app/types/index.d.ts +0 -61
  49. package/dist/modules/agent/runtime/server/Session.d.ts +25 -6
  50. package/dist/modules/agent/runtime/server/Session.js +109 -30
  51. package/dist/modules/agent/runtime/server/SessionManager.d.ts +3 -0
  52. package/dist/modules/agent/runtime/server/SessionManager.js +4 -1
  53. package/dist/modules/agent/runtime/server/agent.js +3 -2
  54. package/dist/modules/agent/runtime/server/default-skills/fixReadability.d.ts +2 -0
  55. package/dist/modules/agent/runtime/server/default-skills/fixReadability.js +69 -0
  56. package/dist/modules/agent/runtime/server/default-system-prompts/page-context.js +28 -0
  57. package/dist/modules/agent/runtime/server/server-tools/index.d.ts +10 -2
  58. package/dist/modules/agent/runtime/server/server-tools/index.js +1 -1
  59. package/dist/modules/agent/runtime/server/server-tools/load_tools/index.js +1 -1
  60. package/dist/modules/agent/runtime/shared/types.d.ts +46 -11
  61. package/dist/modules/agent/runtime/shared/types.js +22 -10
  62. package/dist/modules/charts/index.d.mts +1 -1
  63. package/dist/modules/charts/index.mjs +21 -7
  64. package/dist/modules/charts/runtime/blokkli/skills/charts.js +6 -6
  65. package/dist/modules/charts/runtime/blokkli/tools/chart_schemas.d.ts +25 -2
  66. package/dist/modules/charts/runtime/blokkli/tools/chart_schemas.js +39 -1
  67. package/dist/modules/charts/runtime/blokkli/tools/create_chart/index.js +24 -17
  68. package/dist/modules/charts/runtime/blokkli/tools/get_chart_data/index.js +11 -19
  69. package/dist/modules/charts/runtime/blokkli/tools/get_chart_type_options/index.js +2 -4
  70. package/dist/modules/charts/runtime/blokkli/tools/update_chart/index.js +8 -20
  71. package/dist/modules/charts/runtime/chartTypes/area.d.ts +6 -1
  72. package/dist/modules/charts/runtime/chartTypes/bar.d.ts +7 -1
  73. package/dist/modules/charts/runtime/chartTypes/define.d.ts +1 -1
  74. package/dist/modules/charts/runtime/chartTypes/donut.d.ts +5 -1
  75. package/dist/modules/charts/runtime/chartTypes/heatmap.d.ts +3 -1
  76. package/dist/modules/charts/runtime/chartTypes/index.d.ts +18 -0
  77. package/dist/modules/charts/runtime/chartTypes/line.d.ts +6 -1
  78. package/dist/modules/charts/runtime/chartTypes/pie.d.ts +4 -1
  79. package/dist/modules/charts/runtime/chartTypes/radar.d.ts +6 -1
  80. package/dist/modules/charts/runtime/chartTypes/radialBar.d.ts +5 -1
  81. package/dist/modules/charts/runtime/chartTypes/shared.d.ts +20 -5
  82. package/dist/modules/charts/runtime/chartTypes/types.d.ts +6 -6
  83. package/dist/modules/charts/runtime/components/ChartRenderer/index.d.vue.ts +145 -2
  84. package/dist/modules/charts/runtime/components/ChartRenderer/index.vue +2 -2
  85. package/dist/modules/charts/runtime/components/ChartRenderer/index.vue.d.ts +145 -2
  86. package/dist/modules/charts/runtime/components/index.d.ts +1 -0
  87. package/dist/modules/charts/runtime/components/index.js +1 -0
  88. package/dist/modules/charts/runtime/features/charts/Editor/ChartTypeOptions/index.d.vue.ts +3 -2
  89. package/dist/modules/charts/runtime/features/charts/Editor/ChartTypeOptions/index.vue.d.ts +3 -2
  90. package/dist/modules/charts/runtime/features/charts/Editor/CsvImport/index.vue +1 -2
  91. package/dist/modules/charts/runtime/features/charts/Editor/FootnoteEditor/index.vue +1 -1
  92. package/dist/modules/charts/runtime/features/charts/Editor/Preview/index.d.vue.ts +2 -0
  93. package/dist/modules/charts/runtime/features/charts/Editor/Preview/index.vue +35 -13
  94. package/dist/modules/charts/runtime/features/charts/Editor/Preview/index.vue.d.ts +2 -0
  95. package/dist/modules/charts/runtime/features/charts/Editor/index.d.vue.ts +1 -0
  96. package/dist/modules/charts/runtime/features/charts/Editor/index.vue +9 -3
  97. package/dist/modules/charts/runtime/features/charts/Editor/index.vue.d.ts +1 -0
  98. package/dist/modules/charts/runtime/features/charts/Editor/useChartEditorState.js +1 -1
  99. package/dist/modules/charts/runtime/features/charts/index.vue +6 -6
  100. package/dist/modules/charts/runtime/helpers/index.d.ts +25 -0
  101. package/dist/modules/charts/runtime/helpers/index.js +63 -0
  102. package/dist/modules/charts/runtime/types.d.ts +10 -28
  103. package/dist/modules/charts/runtime/types.js +0 -64
  104. package/dist/modules/drupal/index.d.mts +1 -1
  105. package/dist/modules/drupal/runtime/adapter/index.d.ts +3 -1
  106. package/dist/modules/drupal/runtime/adapter/index.js +4 -4
  107. package/dist/modules/table-of-contents/index.d.mts +1 -1
  108. package/dist/runtime/components/BlokkliItem.vue +1 -1
  109. package/dist/runtime/composables/defineBlokkli.js +1 -1
  110. package/dist/runtime/editor/components/AnimationCanvas/index.vue +13 -7
  111. package/dist/runtime/editor/components/Banner/index.d.vue.ts +1 -0
  112. package/dist/runtime/editor/components/Banner/index.vue +1 -1
  113. package/dist/runtime/editor/components/Banner/index.vue.d.ts +1 -0
  114. package/dist/runtime/editor/components/DropdownItem/index.d.vue.ts +1 -0
  115. package/dist/runtime/editor/components/DropdownItem/index.vue +3 -2
  116. package/dist/runtime/editor/components/DropdownItem/index.vue.d.ts +1 -0
  117. package/dist/runtime/editor/components/EditProvider.vue +7 -4
  118. package/dist/runtime/editor/components/FlexTextarea/index.d.vue.ts +5 -1
  119. package/dist/runtime/editor/components/FlexTextarea/index.vue +24 -101
  120. package/dist/runtime/editor/components/FlexTextarea/index.vue.d.ts +5 -1
  121. package/dist/runtime/editor/components/NestedEditorOverlay/index.vue +28 -9
  122. package/dist/runtime/editor/components/Popup/index.d.vue.ts +30 -0
  123. package/dist/runtime/editor/components/Popup/index.vue +82 -0
  124. package/dist/runtime/editor/components/Popup/index.vue.d.ts +30 -0
  125. package/dist/runtime/editor/components/Resizable/index.vue +4 -1
  126. package/dist/runtime/editor/components/Toolbar/index.vue +107 -6
  127. package/dist/runtime/editor/components/index.d.ts +4 -3
  128. package/dist/runtime/editor/components/index.js +6 -4
  129. package/dist/runtime/editor/composables/defineDropAreas.js +3 -3
  130. package/dist/runtime/editor/composables/defineDropHandler.d.ts +3 -0
  131. package/dist/runtime/editor/composables/defineDropHandler.js +10 -0
  132. package/dist/runtime/editor/composables/index.d.ts +1 -0
  133. package/dist/runtime/editor/composables/index.js +1 -0
  134. package/dist/runtime/editor/css/output.css +1 -1
  135. package/dist/runtime/editor/events/index.d.ts +9 -0
  136. package/dist/runtime/editor/features/add-list/index.vue +58 -1
  137. package/dist/runtime/editor/features/analyze/Main.d.vue.ts +3 -2
  138. package/dist/runtime/editor/features/analyze/Main.vue +28 -44
  139. package/dist/runtime/editor/features/analyze/Main.vue.d.ts +3 -2
  140. package/dist/runtime/editor/features/analyze/analyzers/readability.js +65 -0
  141. package/dist/runtime/editor/features/analyze/analyzers/types.d.ts +19 -0
  142. package/dist/runtime/editor/features/analyze/index.vue +18 -15
  143. package/dist/runtime/editor/features/clipboard/DropElement/Video.d.vue.ts +8 -0
  144. package/dist/runtime/editor/features/clipboard/{List/Item → DropElement}/Video.vue +1 -5
  145. package/dist/runtime/editor/features/clipboard/DropElement/Video.vue.d.ts +8 -0
  146. package/dist/runtime/editor/features/clipboard/DropElement/helpers.d.ts +1 -0
  147. package/dist/runtime/editor/features/clipboard/DropElement/helpers.js +14 -0
  148. package/dist/runtime/editor/features/clipboard/DropElement/index.d.vue.ts +16 -0
  149. package/dist/runtime/editor/features/clipboard/DropElement/index.vue +97 -0
  150. package/dist/runtime/editor/features/clipboard/DropElement/index.vue.d.ts +16 -0
  151. package/dist/runtime/editor/features/clipboard/helpers.d.ts +15 -0
  152. package/dist/runtime/editor/features/clipboard/helpers.js +62 -0
  153. package/dist/runtime/editor/features/clipboard/index.vue +585 -337
  154. package/dist/runtime/editor/features/clipboard/types.d.ts +14 -2
  155. package/dist/runtime/editor/features/dragging-overlay/DragItems/index.vue +17 -5
  156. package/dist/runtime/editor/features/dragging-overlay/Renderer/index.vue +2 -2
  157. package/dist/runtime/editor/features/dragging-overlay/index.vue +125 -219
  158. package/dist/runtime/editor/features/editable-field/Overlay/Plaintext/index.vue +4 -4
  159. package/dist/runtime/editor/features/editable-field/Overlay/index.vue +6 -0
  160. package/dist/runtime/editor/features/library/index.vue +14 -0
  161. package/dist/runtime/editor/features/media-library/index.vue +32 -1
  162. package/dist/runtime/editor/features/options/Form/ComplexType/index.d.vue.ts +11 -0
  163. package/dist/runtime/editor/features/options/Form/ComplexType/index.vue +36 -0
  164. package/dist/runtime/editor/features/options/Form/ComplexType/index.vue.d.ts +11 -0
  165. package/dist/runtime/editor/features/options/Form/Item.d.vue.ts +3 -2
  166. package/dist/runtime/editor/features/options/Form/Item.vue +10 -2
  167. package/dist/runtime/editor/features/options/Form/Item.vue.d.ts +3 -2
  168. package/dist/runtime/editor/features/options/Form/index.vue +5 -0
  169. package/dist/runtime/editor/features/search/index.vue +25 -1
  170. package/dist/runtime/editor/features/structure/index.vue +25 -1
  171. package/dist/runtime/editor/features/tour/index.vue +22 -12
  172. package/dist/runtime/editor/helpers/clipboardData/index.d.ts +11 -0
  173. package/dist/runtime/editor/helpers/clipboardData/index.js +157 -0
  174. package/dist/runtime/editor/helpers/options/index.js +5 -0
  175. package/dist/runtime/editor/icons/svg/stars.svg +5 -1
  176. package/dist/runtime/editor/plugins/Sidebar/Detached/index.d.vue.ts +1 -1
  177. package/dist/runtime/editor/plugins/Sidebar/Detached/index.vue.d.ts +1 -1
  178. package/dist/runtime/editor/plugins/Sidebar/index.d.vue.ts +14 -3
  179. package/dist/runtime/editor/plugins/Sidebar/index.vue +4 -2
  180. package/dist/runtime/editor/plugins/Sidebar/index.vue.d.ts +14 -3
  181. package/dist/runtime/editor/providers/analyze.d.ts +43 -0
  182. package/dist/runtime/editor/providers/analyze.js +78 -0
  183. package/dist/runtime/editor/providers/animation.d.ts +4 -0
  184. package/dist/runtime/editor/providers/animation.js +6 -0
  185. package/dist/runtime/editor/providers/dragdrop.d.ts +55 -0
  186. package/dist/runtime/editor/providers/dragdrop.js +37 -0
  187. package/dist/runtime/editor/providers/storage.js +15 -0
  188. package/dist/runtime/editor/providers/ui.d.ts +6 -0
  189. package/dist/runtime/editor/providers/ui.js +19 -0
  190. package/dist/runtime/editor/translations/de.json +73 -61
  191. package/dist/runtime/editor/translations/fr.json +67 -55
  192. package/dist/runtime/editor/translations/gsw_CH.json +71 -59
  193. package/dist/runtime/editor/translations/it.json +67 -55
  194. package/dist/runtime/editor/types/app.d.ts +4 -2
  195. package/dist/runtime/editor/types/draggable.d.ts +1 -0
  196. package/dist/runtime/editor/types/ui.d.ts +1 -1
  197. package/dist/runtime/helpers/injections.d.ts +1 -1
  198. package/dist/runtime/types/blockOptions.d.ts +2 -1
  199. package/dist/runtime/types/definitions.d.ts +4 -0
  200. package/dist/shared/{editor.CWQIFIEQ.d.mts → editor.BdBm1Z7C.d.mts} +12 -0
  201. package/dist/types.d.mts +1 -1
  202. package/package.json +5 -3
  203. package/dist/modules/charts/runtime/components/Fragment/BlokkliChart.d.vue.ts +0 -3
  204. package/dist/modules/charts/runtime/components/Fragment/BlokkliChart.vue +0 -29
  205. package/dist/modules/charts/runtime/components/Fragment/BlokkliChart.vue.d.ts +0 -3
  206. package/dist/runtime/editor/features/clipboard/List/Item/File.d.vue.ts +0 -4
  207. package/dist/runtime/editor/features/clipboard/List/Item/File.vue +0 -60
  208. package/dist/runtime/editor/features/clipboard/List/Item/File.vue.d.ts +0 -4
  209. package/dist/runtime/editor/features/clipboard/List/Item/Video.d.vue.ts +0 -4
  210. package/dist/runtime/editor/features/clipboard/List/Item/Video.vue.d.ts +0 -4
  211. package/dist/runtime/editor/features/clipboard/List/index.d.vue.ts +0 -11
  212. package/dist/runtime/editor/features/clipboard/List/index.vue +0 -72
  213. package/dist/runtime/editor/features/clipboard/List/index.vue.d.ts +0 -11
  214. package/dist/runtime/editor/features/tour/Popup/index.d.vue.ts +0 -9
  215. package/dist/runtime/editor/features/tour/Popup/index.vue +0 -34
  216. package/dist/runtime/editor/features/tour/Popup/index.vue.d.ts +0 -9
  217. package/dist/runtime/editor/providers/dropArea.d.ts +0 -48
  218. package/dist/runtime/editor/providers/dropArea.js +0 -22
@@ -1,21 +1,4 @@
1
1
  import { z } from "zod";
2
- import { getMutatedOptionValue } from "#blokkli/editor/helpers/options";
3
- import { getRuntimeOptionValue } from "#blokkli/runtime-helpers";
4
- export function extractOptionLabels(option) {
5
- if (!("options" in option) || !option.options) return void 0;
6
- const raw = option.options;
7
- const labels = {};
8
- for (const [key, value] of Object.entries(raw)) {
9
- if (typeof value === "string") {
10
- labels[key] = value;
11
- } else if (typeof value === "object" && value !== null && "label" in value) {
12
- labels[key] = String(value.label);
13
- } else {
14
- labels[key] = key;
15
- }
16
- }
17
- return labels;
18
- }
19
2
  export const blockOptionSchema = z.object({
20
3
  type: z.string().describe(
21
4
  "The option type (checkbox, radios, checkboxes, text, number, range, color, datetime-local)"
@@ -32,54 +15,6 @@ export const blockOptionsMapSchema = z.record(
32
15
  z.string().describe("Option property name"),
33
16
  blockOptionSchema
34
17
  );
35
- export function buildBlockOptionsMap(availableOptions, mutatedOptions, uuid) {
36
- const result = {};
37
- for (const opt of availableOptions) {
38
- const rawValue = getMutatedOptionValue(
39
- mutatedOptions,
40
- uuid,
41
- opt.property,
42
- opt.option.default
43
- );
44
- const currentValue = getRuntimeOptionValue(opt.option, rawValue);
45
- result[opt.property] = buildBlockOptionEntry(opt.option, currentValue);
46
- }
47
- return result;
48
- }
49
- export function buildBlockOptionsMapFromDefinitions(options) {
50
- const result = {};
51
- for (const [key, opt] of Object.entries(options)) {
52
- result[key] = buildBlockOptionEntry(
53
- opt,
54
- opt.default
55
- );
56
- }
57
- return result;
58
- }
59
- function buildBlockOptionEntry(opt, currentValue) {
60
- const entry = {
61
- type: opt.type,
62
- label: opt.label,
63
- currentValue
64
- };
65
- if (opt.description) {
66
- entry.description = opt.description;
67
- }
68
- const labels = extractOptionLabels(opt);
69
- if (labels) {
70
- entry.options = labels;
71
- }
72
- if ("min" in opt) {
73
- entry.min = opt.min;
74
- }
75
- if ("max" in opt) {
76
- entry.max = opt.max;
77
- }
78
- if ("step" in opt && opt.type === "range") {
79
- entry.step = opt.step;
80
- }
81
- return entry;
82
- }
83
18
  export const parentSchema = z.object({
84
19
  type: z.string().describe(
85
20
  "The entity type of the parent. Do NOT guess this - always use the parent object returned by get_child_paragraphs."
@@ -104,131 +39,9 @@ export const optionValueSchema = z.union([
104
39
  z.number(),
105
40
  z.array(z.string())
106
41
  ]);
107
- export function validateOptionValue(key, value, optionDef) {
108
- const optionType = optionDef.option.type;
109
- if (optionType === "checkbox") {
110
- if (typeof value !== "boolean" && value !== "1" && value !== "0" && value !== "true" && value !== "false") {
111
- return `Option "${key}" expects a boolean value`;
112
- }
113
- } else if (optionType === "radios") {
114
- if (typeof value !== "string") {
115
- return `Option "${key}" expects a string value`;
116
- }
117
- if ("options" in optionDef.option && optionDef.option.options) {
118
- const allowedKeys = Object.keys(optionDef.option.options);
119
- if (!allowedKeys.includes(value)) {
120
- return `Option "${key}" value must be one of: ${allowedKeys.join(", ")}`;
121
- }
122
- }
123
- } else if (optionType === "checkboxes") {
124
- if (!Array.isArray(value) && typeof value !== "string") {
125
- return `Option "${key}" expects an array of strings or comma-separated string`;
126
- }
127
- if ("options" in optionDef.option && optionDef.option.options) {
128
- const allowedKeys = Object.keys(optionDef.option.options);
129
- const values = Array.isArray(value) ? value : value.split(",");
130
- for (const v of values) {
131
- if (!allowedKeys.includes(v)) {
132
- return `Option "${key}" value "${v}" is not allowed. Must be one of: ${allowedKeys.join(", ")}`;
133
- }
134
- }
135
- }
136
- } else if (optionType === "number" || optionType === "range") {
137
- const numValue = typeof value === "number" ? value : Number.parseFloat(String(value));
138
- if (Number.isNaN(numValue)) {
139
- return `Option "${key}" expects a numeric value`;
140
- }
141
- if ("min" in optionDef.option && numValue < optionDef.option.min) {
142
- return `Option "${key}" value must be >= ${optionDef.option.min}`;
143
- }
144
- if ("max" in optionDef.option && numValue > optionDef.option.max) {
145
- return `Option "${key}" value must be <= ${optionDef.option.max}`;
146
- }
147
- }
148
- return void 0;
149
- }
150
- export function getFieldType(app, entityType, bundle, fieldName) {
151
- const config = app.types.editableFieldConfig.forName(
152
- entityType,
153
- bundle,
154
- fieldName
155
- );
156
- if (!config) return null;
157
- if (config.type === "table") return null;
158
- if (config.type === "frame" || config.type === "markup") return "markup";
159
- return "plain";
160
- }
161
- export function getEditableValue(app, entityType, uuid, bundle, fieldName, fieldType) {
162
- const editables = app.directive.getEditablesForBlock(uuid);
163
- const editable = editables.find((e) => e.fieldName === fieldName);
164
- if (editable?.getValue) {
165
- return editable.getValue();
166
- }
167
- const element = app.directive.findEditableElement(fieldName, {
168
- type: entityType,
169
- uuid,
170
- bundle
171
- });
172
- if (element) {
173
- return fieldType === "markup" ? element.innerHTML || "" : element.textContent || "";
174
- }
175
- return "";
176
- }
177
- export function getParagraphChildren(app, uuid) {
178
- const result = [];
179
- for (const field of app.state.mutatedFields.value) {
180
- if (field.entityUuid === uuid && field.list.length > 0) {
181
- result.push({
182
- fieldName: field.name,
183
- paragraphs: field.list.map((item) => ({
184
- uuid: item.uuid,
185
- bundle: item.bundle
186
- }))
187
- });
188
- }
189
- }
190
- return result;
191
- }
192
42
  export const positionSchema = z.string().optional().default("end").describe(
193
43
  'Where to place the paragraph(s). "start" = beginning, "end" (default) = append at end, "after:<UUID>" = after a specific paragraph, "before:<UUID>" = before a specific paragraph.'
194
44
  );
195
- export function resolvePosition(app, parentUuid, fieldName, position) {
196
- const fieldList = app.state.mutatedFields.value.find(
197
- (f) => f.entityUuid === parentUuid && f.name === fieldName
198
- );
199
- const list = fieldList?.list ?? [];
200
- if (position === void 0 || position === "end") {
201
- const lastBlock = list.at(-1);
202
- return { afterUuid: lastBlock?.uuid ?? null };
203
- }
204
- if (position === "start") {
205
- return { afterUuid: null };
206
- }
207
- if (position.startsWith("after:")) {
208
- const uuid = position.slice(6);
209
- const found = list.find((b) => b.uuid === uuid);
210
- if (!found) {
211
- return {
212
- error: `Position "after:${uuid}": paragraph not found in field "${fieldName}".`
213
- };
214
- }
215
- return { afterUuid: uuid };
216
- }
217
- if (position.startsWith("before:")) {
218
- const uuid = position.slice(7);
219
- const index = list.findIndex((b) => b.uuid === uuid);
220
- if (index === -1) {
221
- return {
222
- error: `Position "before:${uuid}": paragraph not found in field "${fieldName}".`
223
- };
224
- }
225
- const preceding = index > 0 ? list[index - 1] : void 0;
226
- return { afterUuid: preceding?.uuid ?? null };
227
- }
228
- return {
229
- error: `Invalid position value: "${position}". Use "start", "end", "after:<UUID>", or "before:<UUID>".`
230
- };
231
- }
232
45
  export const mutationSuccessSchema = z.union([
233
46
  z.object({
234
47
  success: z.literal(true),
@@ -13,53 +13,46 @@ const resultSchema = z.array(
13
13
  })
14
14
  );
15
15
  export default defineBlokkliAgentTool({
16
- resolve: async (ctx) => {
17
- if (!ctx.adapter.getContentSearchTabs || !ctx.adapter.getContentSearchResults) {
18
- return [];
19
- }
16
+ name: "search_content",
17
+ description: 'Search for content items by tab ID and query. The available tab IDs and their entity types are listed in the system prompt under "Content Search Tabs". Use the tab ID that matches the type of content you are looking for.',
18
+ category: "query",
19
+ lazy: true,
20
+ requiredAdapterMethods: ["getContentSearchTabs", "getContentSearchResults"],
21
+ modes: ["readonly", "editing", "translating", "review"],
22
+ label($t) {
23
+ return $t("aiAgentSearchContentRunning", "Searching content...");
24
+ },
25
+ paramsSchema: z.object({
26
+ tab: z.string().describe(
27
+ "The tab ID to search in. See the system prompt for available tab IDs."
28
+ ),
29
+ query: z.string().describe("The search query")
30
+ }),
31
+ resultSchema,
32
+ async execute(ctx, params) {
20
33
  const tabs = await ctx.adapter.getContentSearchTabs();
21
- return tabs.map((tab) => {
22
- const typesDescription = tab.types.map((type) => {
23
- return `${type.type} (${type.bundles.join(", ")})`;
24
- }).join(", ");
25
- const description = `Content search for these entities: ${typesDescription}`;
26
- return defineBlokkliAgentTool({
27
- name: `search_content_${tab.id}`,
28
- description,
29
- category: "query",
30
- lazy: true,
31
- requiredAdapterMethods: [
32
- "getContentSearchTabs",
33
- "getContentSearchResults"
34
- ],
35
- modes: ["readonly", "editing", "translating", "review"],
36
- label() {
37
- return `Searching ${tab.title}...`;
38
- },
39
- paramsSchema: z.object({
40
- query: z.string().describe(`Search query for ${tab.title}`)
41
- }),
42
- resultSchema,
43
- async execute(toolCtx, params) {
44
- const items = await toolCtx.adapter.getContentSearchResults(
45
- tab.id,
46
- params.query
47
- );
48
- return {
49
- label: `Searched ${tab.title} for "${params.query}"`,
50
- result: items.map((item) => ({
51
- id: item.id,
52
- title: item.title,
53
- entityType: item.entityType,
54
- entityBundle: item.entityBundle,
55
- targetBundles: item.targetBundles,
56
- context: item.context,
57
- text: item.text,
58
- imageUrl: item.imageUrl
59
- }))
60
- };
61
- }
62
- });
63
- });
34
+ const tab = tabs.find((t) => t.id === params.tab);
35
+ if (!tab) {
36
+ return {
37
+ error: `Invalid tab ID "${params.tab}". Available tabs: ${tabs.map((t) => t.id).join(", ")}`
38
+ };
39
+ }
40
+ const items = await ctx.adapter.getContentSearchResults(
41
+ params.tab,
42
+ params.query
43
+ );
44
+ return {
45
+ label: `Searched ${tab.title} for "${params.query}"`,
46
+ result: items.map((item) => ({
47
+ id: item.id,
48
+ title: item.title,
49
+ entityType: item.entityType,
50
+ entityBundle: item.entityBundle,
51
+ targetBundles: item.targetBundles,
52
+ context: item.context,
53
+ text: item.text,
54
+ imageUrl: item.imageUrl
55
+ }))
56
+ };
64
57
  }
65
58
  });
@@ -4,11 +4,8 @@ import {
4
4
  getAvailableOptions,
5
5
  optionValueToStorable
6
6
  } from "#blokkli/editor/helpers/options";
7
- import {
8
- mutationResultSchema,
9
- optionValueSchema,
10
- validateOptionValue
11
- } from "../schemas.js";
7
+ import { mutationResultSchema, optionValueSchema } from "../schemas.js";
8
+ import { validateOptionValue } from "../helpers.js";
12
9
  import { onlyUnique } from "#blokkli/helpers";
13
10
  const paragraphOptionsSchema = z.object({
14
11
  uuid: z.string().describe("The paragraph UUID"),
@@ -200,67 +200,6 @@ export type McpToolDefinition<TParamsSchema extends z.ZodType = z.ZodType, TResu
200
200
  */
201
201
  mockParamsVariants?: () => z.infer<TParamsSchema>[];
202
202
  };
203
- /**
204
- * A tool definition with a relaxed execute signature.
205
- *
206
- * Used as the return type for factory resolve callbacks. Preserves structural
207
- * checking on all other properties (catches typos and excess properties) while
208
- * allowing each tool to have its own specific execute signature via
209
- * defineBlokkliAgentTool().
210
- */
211
- export type FactoryResolvedTool = {
212
- name: string;
213
- description: string;
214
- icon?: string;
215
- category: McpToolCategory;
216
- label: ($t: TranslationFunction) => string;
217
- paramsSchema: z.ZodType;
218
- resultSchema: z.ZodType;
219
- requiredAdapterMethods?: readonly AdapterMethods[];
220
- modes: EditMode[];
221
- component?: Component;
222
- requiresApproval?: boolean;
223
- lazy?: boolean;
224
- volatile?: boolean;
225
- prunedSummary?: (result: any) => string;
226
- execute: (...args: any[]) => any;
227
- mockParams?: () => any;
228
- mockParamsVariants?: () => any[];
229
- };
230
- /**
231
- * Input for a tool factory that dynamically creates tools at runtime.
232
- *
233
- * Instead of defining a single static tool, a factory uses a `resolve` callback
234
- * that is called when the agent connects. The callback returns an array of
235
- * McpToolDefinition objects, allowing tools to be created based on runtime state
236
- * (e.g., available content search tabs from the adapter).
237
- */
238
- export type McpToolFactoryInput = {
239
- /**
240
- * Called once when the agent connects. Returns an array of tool definitions
241
- * that are registered as if they were statically defined.
242
- *
243
- * Each returned tool is a full McpToolDefinition with its own
244
- * requiredAdapterMethods, execute function, and schemas. Use
245
- * defineBlokkliAgentTool() for each tool to get full type inference.
246
- *
247
- * The context provides access to the app and adapter so the factory can
248
- * query runtime state (e.g., available content search tabs) to decide
249
- * which tools to create. If adapter methods are optional, check for their
250
- * existence before calling them (or return an empty array).
251
- */
252
- resolve: (context: McpToolContext) => Promise<FactoryResolvedTool[]> | FactoryResolvedTool[];
253
- };
254
- /**
255
- * A tool factory with the __factory marker for runtime identification.
256
- */
257
- export type McpToolFactory = McpToolFactoryInput & {
258
- __factory: true;
259
- };
260
- /**
261
- * A tool item is either a static tool definition or a factory that produces tools.
262
- */
263
- export type McpToolItem = McpToolDefinition | McpToolFactory;
264
203
  /**
265
204
  * A pre-defined agent prompt that users can select.
266
205
  */
@@ -1,5 +1,5 @@
1
1
  import type { Peer } from 'crossws';
2
- import type { PageContext, ClientToolDefinition, ConversationStateSnapshot, GenericMessage } from '../shared/types.js';
2
+ import type { PageContext, ClientToolDefinition, ServerToolMetadata, ConversationStateSnapshot, GenericMessage } from '../shared/types.js';
3
3
  import type { ServerPlan } from './server-tools/index.js';
4
4
  export declare class Session {
5
5
  messages: GenericMessage[];
@@ -12,10 +12,10 @@ export declare class Session {
12
12
  }>;
13
13
  abortController: AbortController | null;
14
14
  isProcessing: boolean;
15
- /** Eager tools sent to the LLM on every turn */
16
- tools: ClientToolDefinition[];
17
- /** Lazy tools held back until activated via load_tools */
18
- lazyTools: ClientToolDefinition[];
15
+ /** Names of eager tools sent to the LLM on every turn */
16
+ toolNames: string[];
17
+ /** Names of lazy tools held back until activated via load_tools */
18
+ lazyToolNames: string[];
19
19
  /** Names of lazy tools that have been activated via load_tools */
20
20
  activatedLazyTools: Set<string>;
21
21
  /** Names of skills that have been loaded via load_skill */
@@ -32,7 +32,26 @@ export declare class Session {
32
32
  private unprunedMessages;
33
33
  /** Last generic tool definitions for transcript */
34
34
  private lastTools;
35
- init(tools: ClientToolDefinition[], pageContext: PageContext): void;
35
+ /** Bundled tool metadata map for server-side resolution */
36
+ private bundledToolMap;
37
+ /** Cache for resolved JSON Schemas (Zod→JSON Schema is deterministic) */
38
+ private jsonSchemaCache;
39
+ constructor(toolDefinitions: ServerToolMetadata[]);
40
+ /**
41
+ * Resolve a single tool name into a ClientToolDefinition.
42
+ * Resolves from bundled metadata. Caches the JSON Schema conversion.
43
+ */
44
+ resolveToolDefinition(name: string): ClientToolDefinition | undefined;
45
+ /**
46
+ * Resolve multiple tool names into ClientToolDefinition objects.
47
+ * Skips names that cannot be resolved.
48
+ */
49
+ resolveToolDefinitions(names: string[]): ClientToolDefinition[];
50
+ /**
51
+ * Look up name + description for a tool.
52
+ */
53
+ private getToolSummary;
54
+ init(toolNames: string[], pageContext: PageContext): void;
36
55
  start(peer: Peer, prompt: string, apiKey: string, authSecret: string, selectedUuids?: string[]): void;
37
56
  resolveToolResult(callId: string, result: {
38
57
  result: unknown;
@@ -1,3 +1,4 @@
1
+ import { z } from "zod";
1
2
  import { buildSystemPrompt, buildSystemPromptEntries } from "./agentPrompt.js";
2
3
  import { provider, models } from "#blokkli-build/agent-server";
3
4
  import {
@@ -12,7 +13,7 @@ import {
12
13
  verifyStateHash,
13
14
  validateMessages
14
15
  } from "./helpers.js";
15
- import { buildDefinition } from "./server-tools/index.js";
16
+ import { buildDefinition, stripSchemaOverhead } from "./server-tools/index.js";
16
17
  import loadSkillTool from "./server-tools/load_skill/index.js";
17
18
  import loadToolsTool from "./server-tools/load_tools/index.js";
18
19
  import createPlanTool from "./server-tools/create_plan/index.js";
@@ -28,10 +29,10 @@ export class Session {
28
29
  pendingToolCalls = /* @__PURE__ */ new Map();
29
30
  abortController = null;
30
31
  isProcessing = false;
31
- /** Eager tools sent to the LLM on every turn */
32
- tools = [];
33
- /** Lazy tools held back until activated via load_tools */
34
- lazyTools = [];
32
+ /** Names of eager tools sent to the LLM on every turn */
33
+ toolNames = [];
34
+ /** Names of lazy tools held back until activated via load_tools */
35
+ lazyToolNames = [];
35
36
  /** Names of lazy tools that have been activated via load_tools */
36
37
  activatedLazyTools = /* @__PURE__ */ new Set();
37
38
  /** Names of skills that have been loaded via load_skill */
@@ -46,12 +47,73 @@ export class Session {
46
47
  unprunedMessages = [];
47
48
  /** Last generic tool definitions for transcript */
48
49
  lastTools = [];
50
+ /** Bundled tool metadata map for server-side resolution */
51
+ bundledToolMap;
52
+ /** Cache for resolved JSON Schemas (Zod→JSON Schema is deterministic) */
53
+ jsonSchemaCache = /* @__PURE__ */ new Map();
54
+ constructor(toolDefinitions) {
55
+ this.bundledToolMap = new Map(toolDefinitions.map((t) => [t.name, t]));
56
+ }
57
+ /**
58
+ * Resolve a single tool name into a ClientToolDefinition.
59
+ * Resolves from bundled metadata. Caches the JSON Schema conversion.
60
+ */
61
+ resolveToolDefinition(name) {
62
+ const bundled = this.bundledToolMap.get(name);
63
+ if (!bundled) return void 0;
64
+ let inputSchema = this.jsonSchemaCache.get(name);
65
+ if (!inputSchema) {
66
+ inputSchema = stripSchemaOverhead(
67
+ z.toJSONSchema(bundled.paramsSchema)
68
+ );
69
+ this.jsonSchemaCache.set(name, inputSchema);
70
+ }
71
+ return {
72
+ name: bundled.name,
73
+ description: bundled.description,
74
+ input_schema: inputSchema,
75
+ ...bundled.lazy ? { lazy: true } : {},
76
+ category: bundled.category,
77
+ ...bundled.volatile ? { volatile: true } : {}
78
+ };
79
+ }
80
+ /**
81
+ * Resolve multiple tool names into ClientToolDefinition objects.
82
+ * Skips names that cannot be resolved.
83
+ */
84
+ resolveToolDefinitions(names) {
85
+ const result = [];
86
+ for (const name of names) {
87
+ const def = this.resolveToolDefinition(name);
88
+ if (def) {
89
+ result.push(def);
90
+ }
91
+ }
92
+ return result;
93
+ }
94
+ /**
95
+ * Look up name + description for a tool.
96
+ */
97
+ getToolSummary(name) {
98
+ const bundled = this.bundledToolMap.get(name);
99
+ if (!bundled) return void 0;
100
+ return { name: bundled.name, description: bundled.description };
101
+ }
49
102
  // --------------------------------------------------------------------------
50
103
  // Public methods
51
104
  // --------------------------------------------------------------------------
52
- init(tools, pageContext) {
53
- this.tools = tools.filter((t) => !t.lazy);
54
- this.lazyTools = tools.filter((t) => !!t.lazy);
105
+ init(toolNames, pageContext) {
106
+ this.toolNames = [];
107
+ this.lazyToolNames = [];
108
+ for (const name of toolNames) {
109
+ const bundled = this.bundledToolMap.get(name);
110
+ const isLazy = bundled?.lazy ?? false;
111
+ if (isLazy) {
112
+ this.lazyToolNames.push(name);
113
+ } else {
114
+ this.toolNames.push(name);
115
+ }
116
+ }
55
117
  this.activatedLazyTools = /* @__PURE__ */ new Set();
56
118
  this.loadedSkills = /* @__PURE__ */ new Set();
57
119
  this.pageContext = pageContext;
@@ -142,8 +204,8 @@ export class Session {
142
204
  }
143
205
  this.plan = null;
144
206
  this.messages = [];
145
- this.tools = [];
146
- this.lazyTools = [];
207
+ this.toolNames = [];
208
+ this.lazyToolNames = [];
147
209
  this.activatedLazyTools.clear();
148
210
  this.loadedSkills.clear();
149
211
  this.pageContext = void 0;
@@ -188,7 +250,7 @@ export class Session {
188
250
  this.messages = state.messages;
189
251
  this.unprunedMessages = [];
190
252
  this.lastTools = [];
191
- const validLazyToolNames = new Set(this.lazyTools.map((t) => t.name));
253
+ const validLazyToolNames = new Set(this.lazyToolNames);
192
254
  this.activatedLazyTools = new Set(
193
255
  state.activatedLazyTools.filter((name) => validLazyToolNames.has(name))
194
256
  );
@@ -240,7 +302,7 @@ export class Session {
240
302
  });
241
303
  }
242
304
  async runAgentLoop(peer, prompt, apiKey, authSecret, selectedUuids) {
243
- if (this.tools.length === 0) {
305
+ if (this.toolNames.length === 0) {
244
306
  send(peer, {
245
307
  type: "error",
246
308
  errorType: "bad_request",
@@ -257,10 +319,9 @@ export class Session {
257
319
  return;
258
320
  }
259
321
  const resolvedSkills = resolveSkills(this.pageContext);
260
- const lazyToolSummaries = this.lazyTools.map((t) => ({
261
- name: t.name,
262
- description: t.description
263
- }));
322
+ const lazyToolSummaries = this.lazyToolNames.map((name) => this.getToolSummary(name)).filter(
323
+ (s) => s !== void 0
324
+ );
264
325
  const userParts = [];
265
326
  if (selectedUuids?.length) {
266
327
  userParts.push(
@@ -295,11 +356,16 @@ export class Session {
295
356
  let currentToolUse = null;
296
357
  let currentTextContent = "";
297
358
  let inTextBlock = false;
298
- const activatedTools = this.lazyTools.filter(
299
- (t) => this.activatedLazyTools.has(t.name)
359
+ const eagerTools = this.resolveToolDefinitions(this.toolNames);
360
+ const activatedToolNames = this.lazyToolNames.filter(
361
+ (name) => this.activatedLazyTools.has(name)
362
+ );
363
+ const activatedTools = this.resolveToolDefinitions(activatedToolNames);
364
+ const unloadedLazyToolNames = this.lazyToolNames.filter(
365
+ (name) => !this.activatedLazyTools.has(name)
300
366
  );
301
- const unloadedLazyTools = this.lazyTools.filter(
302
- (t) => !this.activatedLazyTools.has(t.name)
367
+ const unloadedLazyTools = unloadedLazyToolNames.map((name) => this.getToolSummary(name)).filter(
368
+ (s) => s !== void 0
303
369
  );
304
370
  const defCtx = {
305
371
  resolvedSkills,
@@ -307,7 +373,7 @@ export class Session {
307
373
  unloadedLazyTools
308
374
  };
309
375
  const serverToolDefs = serverTools.map((t) => buildDefinition(t, defCtx)).filter((d) => d !== null);
310
- const allTools = [...serverToolDefs, ...this.tools, ...activatedTools];
376
+ const allTools = [...serverToolDefs, ...eagerTools, ...activatedTools];
311
377
  this.lastTools = allTools;
312
378
  const systemPrompt = buildSystemPrompt(
313
379
  this.pageContext,
@@ -440,7 +506,7 @@ export class Session {
440
506
  toolUseId: currentToolUse.id,
441
507
  send: (msg) => send(peer, msg),
442
508
  resolvedSkills,
443
- lazyTools: this.lazyTools,
509
+ lazyToolNames: this.lazyToolNames,
444
510
  activatedLazyTools: this.activatedLazyTools,
445
511
  loadedSkills: this.loadedSkills,
446
512
  plan: this.plan,
@@ -476,7 +542,20 @@ export class Session {
476
542
  }
477
543
  };
478
544
  try {
479
- const parsed = matchedServerTool.inputSchema(defCtx).parse(input);
545
+ const coercedInput = {};
546
+ for (const key of Object.keys(input)) {
547
+ const value = input[key];
548
+ if (typeof value === "string" && (value[0] === "[" || value[0] === "{")) {
549
+ try {
550
+ coercedInput[key] = JSON.parse(value);
551
+ } catch {
552
+ coercedInput[key] = value;
553
+ }
554
+ } else {
555
+ coercedInput[key] = value;
556
+ }
557
+ }
558
+ const parsed = matchedServerTool.inputSchema(defCtx).parse(coercedInput);
480
559
  const result = await matchedServerTool.handle(
481
560
  handlerCtx,
482
561
  parsed
@@ -695,9 +774,10 @@ export class Session {
695
774
  */
696
775
  buildToolMetadataMap() {
697
776
  const map = /* @__PURE__ */ new Map();
698
- for (const tool of [...this.tools, ...this.lazyTools]) {
699
- if (tool.volatile) {
700
- map.set(tool.name, { volatile: true });
777
+ for (const name of [...this.toolNames, ...this.lazyToolNames]) {
778
+ const bundled = this.bundledToolMap.get(name);
779
+ if (bundled?.volatile) {
780
+ map.set(name, { volatile: true });
701
781
  }
702
782
  }
703
783
  return map;
@@ -706,10 +786,9 @@ export class Session {
706
786
  const system = this.pageContext ? buildSystemPromptEntries(
707
787
  this.pageContext,
708
788
  resolveSkills(this.pageContext),
709
- this.lazyTools.map((t) => ({
710
- name: t.name,
711
- description: t.description
712
- })),
789
+ this.lazyToolNames.map((name) => this.getToolSummary(name)).filter(
790
+ (s) => s !== void 0
791
+ ),
713
792
  this.getActivePlanContext(),
714
793
  this.loadedSkills
715
794
  ) : [];
@@ -1,9 +1,12 @@
1
1
  import { Session } from './Session.js';
2
+ import type { ServerToolMetadata } from '../shared/types.js';
2
3
  export declare class SessionManager {
4
+ private toolDefinitions;
3
5
  private sessions;
4
6
  /** Maps used token strings to their embedded timestamp (seconds). */
5
7
  private usedTokens;
6
8
  private pruneTimer;
9
+ constructor(toolDefinitions: ServerToolMetadata[]);
7
10
  create(peerId: string): Session;
8
11
  get(peerId: string): Session | undefined;
9
12
  /**