@blokkli/editor 2.0.0-alpha.35 → 2.0.0-alpha.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/global/types/blockOptions.d.ts +9 -2
- package/dist/global/types/definitions.d.ts +12 -5
- package/dist/module.d.mts +2 -2
- package/dist/module.json +1 -1
- package/dist/module.mjs +56 -4
- package/dist/modules/agent/index.d.mts +1 -1
- package/dist/modules/agent/index.mjs +38 -20
- package/dist/modules/agent/runtime/app/composables/agentProvider.d.ts +2 -2
- package/dist/modules/agent/runtime/app/composables/agentProvider.js +3 -3
- package/dist/modules/agent/runtime/app/features/agent/Panel/Input/Actions/index.vue +34 -60
- package/dist/modules/agent/runtime/app/features/agent/Transcript/index.d.vue.ts +8 -0
- package/dist/modules/agent/runtime/app/features/agent/Transcript/index.vue +138 -0
- package/dist/modules/agent/runtime/app/features/agent/Transcript/index.vue.d.ts +8 -0
- package/dist/modules/agent/runtime/app/features/agent/index.vue +5 -1
- package/dist/modules/agent/runtime/app/tools/get_bundle_info/index.js +175 -0
- package/dist/modules/agent/runtime/app/tools/get_paragraph_context/index.js +5 -0
- package/dist/modules/agent/runtime/app/tools/schemas.d.ts +10 -1
- package/dist/modules/agent/runtime/app/tools/schemas.js +36 -23
- package/dist/modules/agent/runtime/server/Session.d.ts +4 -2
- package/dist/modules/agent/runtime/server/Session.js +61 -57
- package/dist/modules/agent/runtime/server/agentPrompt.d.ts +9 -1
- package/dist/modules/agent/runtime/server/agentPrompt.js +26 -0
- package/dist/modules/agent/runtime/shared/types.d.ts +35 -1
- package/dist/modules/charts/index.d.mts +35 -0
- package/dist/modules/charts/index.mjs +43 -0
- package/dist/modules/charts/runtime/blokkli/skills/charts.d.ts +2 -0
- package/dist/modules/charts/runtime/blokkli/skills/charts.js +42 -0
- package/dist/modules/charts/runtime/blokkli/tools/chart_schemas.d.ts +63 -0
- package/dist/modules/charts/runtime/blokkli/tools/chart_schemas.js +98 -0
- package/dist/modules/charts/runtime/blokkli/tools/create_chart/index.d.ts +2 -0
- package/dist/modules/charts/runtime/blokkli/tools/create_chart/index.js +86 -0
- package/dist/modules/charts/runtime/blokkli/tools/get_chart_data/index.d.ts +2 -0
- package/dist/modules/charts/runtime/blokkli/tools/get_chart_data/index.js +74 -0
- package/dist/modules/charts/runtime/blokkli/tools/get_chart_type_options/index.d.ts +2 -0
- package/dist/modules/charts/runtime/blokkli/tools/get_chart_type_options/index.js +42 -0
- package/dist/modules/charts/runtime/blokkli/tools/update_chart/index.d.ts +2 -0
- package/dist/modules/charts/runtime/blokkli/tools/update_chart/index.js +101 -0
- package/dist/modules/charts/runtime/chartTypes/area.d.ts +2 -0
- package/dist/modules/charts/runtime/chartTypes/area.js +68 -0
- package/dist/modules/charts/runtime/chartTypes/bar.d.ts +2 -0
- package/dist/modules/charts/runtime/chartTypes/bar.js +76 -0
- package/dist/modules/charts/runtime/chartTypes/define.d.ts +2 -0
- package/dist/modules/charts/runtime/chartTypes/define.js +3 -0
- package/dist/modules/charts/runtime/chartTypes/donut.d.ts +2 -0
- package/dist/modules/charts/runtime/chartTypes/donut.js +45 -0
- package/dist/modules/charts/runtime/chartTypes/heatmap.d.ts +2 -0
- package/dist/modules/charts/runtime/chartTypes/heatmap.js +54 -0
- package/dist/modules/charts/runtime/chartTypes/index.d.ts +21 -0
- package/dist/modules/charts/runtime/chartTypes/index.js +47 -0
- package/dist/modules/charts/runtime/chartTypes/line.d.ts +2 -0
- package/dist/modules/charts/runtime/chartTypes/line.js +68 -0
- package/dist/modules/charts/runtime/chartTypes/pie.d.ts +2 -0
- package/dist/modules/charts/runtime/chartTypes/pie.js +28 -0
- package/dist/modules/charts/runtime/chartTypes/radar.d.ts +2 -0
- package/dist/modules/charts/runtime/chartTypes/radar.js +52 -0
- package/dist/modules/charts/runtime/chartTypes/radialBar.d.ts +2 -0
- package/dist/modules/charts/runtime/chartTypes/radialBar.js +44 -0
- package/dist/modules/charts/runtime/chartTypes/shared.d.ts +52 -0
- package/dist/modules/charts/runtime/chartTypes/shared.js +103 -0
- package/dist/modules/charts/runtime/chartTypes/types.d.ts +29 -0
- package/dist/modules/charts/runtime/chartTypes/types.js +0 -0
- package/dist/modules/charts/runtime/components/ChartRenderer/index.d.vue.ts +4 -0
- package/dist/modules/charts/runtime/components/ChartRenderer/index.vue +120 -0
- package/dist/modules/charts/runtime/components/ChartRenderer/index.vue.d.ts +4 -0
- package/dist/modules/charts/runtime/components/Fragment/BlokkliChart.d.vue.ts +3 -0
- package/dist/modules/charts/runtime/components/Fragment/BlokkliChart.vue +29 -0
- package/dist/modules/charts/runtime/components/Fragment/BlokkliChart.vue.d.ts +3 -0
- package/dist/modules/charts/runtime/features/charts/Editor/ChartTypeOptions/index.d.vue.ts +15 -0
- package/dist/modules/charts/runtime/features/charts/Editor/ChartTypeOptions/index.vue +97 -0
- package/dist/modules/charts/runtime/features/charts/Editor/ChartTypeOptions/index.vue.d.ts +15 -0
- package/dist/modules/charts/runtime/features/charts/Editor/ChartTypePicker/index.d.vue.ts +11 -0
- package/dist/modules/charts/runtime/features/charts/Editor/ChartTypePicker/index.vue +34 -0
- package/dist/modules/charts/runtime/features/charts/Editor/ChartTypePicker/index.vue.d.ts +11 -0
- package/dist/modules/charts/runtime/features/charts/Editor/ColorDropdown/index.d.vue.ts +12 -0
- package/dist/modules/charts/runtime/features/charts/Editor/ColorDropdown/index.vue +49 -0
- package/dist/modules/charts/runtime/features/charts/Editor/ColorDropdown/index.vue.d.ts +12 -0
- package/dist/modules/charts/runtime/features/charts/Editor/CsvImport/index.d.vue.ts +19 -0
- package/dist/modules/charts/runtime/features/charts/Editor/CsvImport/index.vue +90 -0
- package/dist/modules/charts/runtime/features/charts/Editor/CsvImport/index.vue.d.ts +19 -0
- package/dist/modules/charts/runtime/features/charts/Editor/DataTable/index.d.vue.ts +23 -0
- package/dist/modules/charts/runtime/features/charts/Editor/DataTable/index.vue +224 -0
- package/dist/modules/charts/runtime/features/charts/Editor/DataTable/index.vue.d.ts +23 -0
- package/dist/modules/charts/runtime/features/charts/Editor/FootnoteEditor/index.d.vue.ts +10 -0
- package/dist/modules/charts/runtime/features/charts/Editor/FootnoteEditor/index.vue +61 -0
- package/dist/modules/charts/runtime/features/charts/Editor/FootnoteEditor/index.vue.d.ts +10 -0
- package/dist/modules/charts/runtime/features/charts/Editor/Preview/index.d.vue.ts +8 -0
- package/dist/modules/charts/runtime/features/charts/Editor/Preview/index.vue +23 -0
- package/dist/modules/charts/runtime/features/charts/Editor/Preview/index.vue.d.ts +8 -0
- package/dist/modules/charts/runtime/features/charts/Editor/index.d.vue.ts +10 -0
- package/dist/modules/charts/runtime/features/charts/Editor/index.vue +243 -0
- package/dist/modules/charts/runtime/features/charts/Editor/index.vue.d.ts +10 -0
- package/dist/modules/charts/runtime/features/charts/Editor/useChartEditorState.d.ts +17 -0
- package/dist/modules/charts/runtime/features/charts/Editor/useChartEditorState.js +90 -0
- package/dist/modules/charts/runtime/features/charts/index.d.vue.ts +3 -0
- package/dist/modules/charts/runtime/features/charts/index.vue +72 -0
- package/dist/modules/charts/runtime/features/charts/index.vue.d.ts +3 -0
- package/dist/modules/charts/runtime/helpers/index.d.ts +1 -0
- package/dist/modules/charts/runtime/helpers/index.js +17 -0
- package/dist/modules/charts/runtime/types.d.ts +51 -0
- package/dist/modules/charts/runtime/types.js +64 -0
- package/dist/modules/drupal/graphql/features/fragments.graphql +2 -0
- package/dist/modules/drupal/index.d.mts +1 -1
- package/dist/modules/drupal/runtime/adapter/index.js +12 -8
- package/dist/modules/table-of-contents/index.d.mts +11 -0
- package/dist/modules/table-of-contents/index.mjs +24 -0
- package/dist/modules/table-of-contents/runtime/components/BlokkliTableOfContents/index.d.vue.ts +44 -0
- package/dist/modules/table-of-contents/runtime/components/BlokkliTableOfContents/index.vue +43 -0
- package/dist/modules/table-of-contents/runtime/components/BlokkliTableOfContents/index.vue.d.ts +44 -0
- package/dist/modules/table-of-contents/runtime/types/index.d.ts +4 -0
- package/dist/modules/table-of-contents/runtime/types/index.js +0 -0
- package/dist/runtime/components/Blocks/Fragment/index.vue +6 -2
- package/dist/runtime/components/BlokkliItem.vue +8 -3
- package/dist/runtime/components/BlokkliProvider.d.vue.ts +7 -0
- package/dist/runtime/components/BlokkliProvider.vue +7 -1
- package/dist/runtime/components/BlokkliProvider.vue.d.ts +7 -0
- package/dist/runtime/composables/useBlokkliHelper.js +4 -2
- package/dist/runtime/editor/components/AnimationCanvas/index.vue +4 -20
- package/dist/runtime/editor/components/Banner/index.d.vue.ts +12 -2
- package/dist/runtime/editor/components/Banner/index.vue +4 -2
- package/dist/runtime/editor/components/Banner/index.vue.d.ts +12 -2
- package/dist/runtime/editor/components/Dropdown/index.d.vue.ts +27 -0
- package/dist/runtime/editor/components/Dropdown/index.vue +107 -0
- package/dist/runtime/editor/components/Dropdown/index.vue.d.ts +27 -0
- package/dist/{modules/agent/runtime/app/features/agent/Panel/Input/Actions → runtime/editor/components}/DropdownItem/index.vue +1 -1
- package/dist/runtime/editor/components/EditProvider.d.vue.ts +2 -0
- package/dist/runtime/editor/components/EditProvider.vue +4 -3
- package/dist/runtime/editor/components/EditProvider.vue.d.ts +2 -0
- package/dist/runtime/editor/components/Form/Radio/index.d.vue.ts +1 -0
- package/dist/runtime/editor/components/Form/Radio/index.vue +3 -2
- package/dist/runtime/editor/components/Form/Radio/index.vue.d.ts +1 -0
- package/dist/runtime/editor/components/ItemIcon/index.vue +10 -2
- package/dist/runtime/editor/components/NestedEditorOverlay/index.d.vue.ts +13 -3
- package/dist/runtime/editor/components/NestedEditorOverlay/index.vue +15 -7
- package/dist/runtime/editor/components/NestedEditorOverlay/index.vue.d.ts +13 -3
- package/dist/runtime/editor/components/PreviewProvider.d.vue.ts +2 -0
- package/dist/runtime/editor/components/PreviewProvider.vue +3 -2
- package/dist/runtime/editor/components/PreviewProvider.vue.d.ts +2 -0
- package/dist/runtime/editor/components/ShortcutIndicator/index.vue +1 -1
- package/dist/runtime/editor/components/index.d.ts +3 -1
- package/dist/runtime/editor/components/index.js +4 -0
- package/dist/runtime/editor/composables/onElementResize.js +0 -1
- package/dist/runtime/editor/composables/useEditableFieldOverride.js +4 -5
- package/dist/runtime/editor/css/output.css +1 -1
- package/dist/runtime/editor/events/index.d.ts +7 -0
- package/dist/runtime/editor/features/add-list/Help/Item.vue +5 -2
- package/dist/runtime/editor/features/artboard/Renderer.vue +1 -1
- package/dist/runtime/editor/features/clipboard/index.vue +1 -1
- package/dist/runtime/editor/features/debug/index.vue +1 -1
- package/dist/runtime/editor/features/dev-mode/index.vue +86 -2
- package/dist/runtime/editor/features/edit/index.vue +20 -0
- package/dist/runtime/editor/features/fragments/types.d.ts +1 -0
- package/dist/runtime/editor/features/hover/Renderer/index.vue +30 -3
- package/dist/runtime/editor/features/hover/index.vue +1 -1
- package/dist/runtime/editor/features/options/Form/Checkbox/index.d.vue.ts +2 -2
- package/dist/runtime/editor/features/options/Form/Checkbox/index.vue +3 -3
- package/dist/runtime/editor/features/options/Form/Checkbox/index.vue.d.ts +2 -2
- package/dist/runtime/editor/features/options/Form/Checkboxes/index.d.vue.ts +2 -2
- package/dist/runtime/editor/features/options/Form/Checkboxes/index.vue +5 -5
- package/dist/runtime/editor/features/options/Form/Checkboxes/index.vue.d.ts +2 -2
- package/dist/runtime/editor/features/options/Form/Item.d.vue.ts +2 -2
- package/dist/runtime/editor/features/options/Form/Item.vue +14 -48
- package/dist/runtime/editor/features/options/Form/Item.vue.d.ts +2 -2
- package/dist/runtime/editor/features/options/Form/Number/index.d.vue.ts +3 -3
- package/dist/runtime/editor/features/options/Form/Number/index.vue +7 -17
- package/dist/runtime/editor/features/options/Form/Number/index.vue.d.ts +3 -3
- package/dist/runtime/editor/features/options/Form/Range/index.d.vue.ts +2 -2
- package/dist/runtime/editor/features/options/Form/Range/index.vue +4 -4
- package/dist/runtime/editor/features/options/Form/Range/index.vue.d.ts +2 -2
- package/dist/runtime/editor/features/options/Form/index.vue +10 -5
- package/dist/runtime/editor/features/selection/index.vue +2 -2
- package/dist/runtime/editor/features/transform/index.vue +1 -3
- package/dist/runtime/editor/plugins/Sidebar/index.d.vue.ts +1 -1
- package/dist/runtime/editor/plugins/Sidebar/index.vue.d.ts +1 -1
- package/dist/runtime/editor/providers/definition.d.ts +2 -2
- package/dist/runtime/editor/providers/definition.js +7 -1
- package/dist/runtime/editor/providers/dom.d.ts +5 -0
- package/dist/runtime/editor/providers/dom.js +11 -2
- package/dist/runtime/editor/providers/fields.d.ts +19 -1
- package/dist/runtime/editor/providers/fields.js +54 -2
- package/dist/runtime/editor/translations/de.json +269 -1
- package/dist/runtime/editor/translations/fr.json +269 -1
- package/dist/runtime/editor/translations/gsw_CH.json +269 -1
- package/dist/runtime/editor/translations/it.json +269 -1
- package/dist/runtime/helpers/imports/index.d.ts +8 -1
- package/dist/runtime/helpers/imports/index.js +15 -6
- package/dist/runtime/helpers/injections.d.ts +5 -1
- package/dist/runtime/helpers/injections.js +3 -0
- package/dist/runtime/helpers/runtimeHelpers/index.js +14 -0
- package/dist/runtime/types/definitions.d.ts +8 -5
- package/dist/runtime/types/provider.d.ts +2 -0
- package/dist/shared/editor.6D5vApr0.mjs +30 -0
- package/dist/shared/{editor.DMFfaLVE.mjs → editor.BFIzNSQM.mjs} +1 -30
- package/dist/shared/{editor.Iax3GCvt.d.mts → editor.CWQIFIEQ.d.mts} +22 -0
- package/dist/types.d.mts +1 -1
- package/package.json +17 -1
- package/dist/modules/agent/runtime/app/tools/get_available_bundles/index.js +0 -104
- /package/dist/modules/agent/runtime/app/tools/{get_available_bundles → get_bundle_info}/index.d.ts +0 -0
- /package/dist/{modules/agent/runtime/app/features/agent/Panel/Input/Actions → runtime/editor/components}/DropdownItem/index.d.vue.ts +0 -0
- /package/dist/{modules/agent/runtime/app/features/agent/Panel/Input/Actions → runtime/editor/components}/DropdownItem/index.vue.d.ts +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildSystemPrompt,
|
|
1
|
+
import { buildSystemPrompt, buildSystemPromptEntries } from "./agentPrompt.js";
|
|
2
2
|
import { provider, models } from "#blokkli-build/agent-server";
|
|
3
3
|
import {
|
|
4
4
|
send,
|
|
@@ -42,8 +42,10 @@ export class Session {
|
|
|
42
42
|
plan = null;
|
|
43
43
|
/** Pending plan approval promise resolver */
|
|
44
44
|
pendingPlanApproval = null;
|
|
45
|
-
/**
|
|
46
|
-
|
|
45
|
+
/** Pre-pruned messages snapshot for transcript (captured before pruneMessages) */
|
|
46
|
+
unprunedMessages = [];
|
|
47
|
+
/** Last generic tool definitions for transcript */
|
|
48
|
+
lastTools = [];
|
|
47
49
|
// --------------------------------------------------------------------------
|
|
48
50
|
// Public methods
|
|
49
51
|
// --------------------------------------------------------------------------
|
|
@@ -110,12 +112,14 @@ export class Session {
|
|
|
110
112
|
getTranscript(peer) {
|
|
111
113
|
send(peer, {
|
|
112
114
|
type: "transcript",
|
|
113
|
-
|
|
115
|
+
transcript: this.buildTranscript()
|
|
114
116
|
});
|
|
115
117
|
}
|
|
116
118
|
newConversation(peer, authSecret) {
|
|
117
119
|
this.abortController?.abort();
|
|
118
120
|
this.messages = [];
|
|
121
|
+
this.unprunedMessages = [];
|
|
122
|
+
this.lastTools = [];
|
|
119
123
|
this.activatedLazyTools.clear();
|
|
120
124
|
this.loadedSkills.clear();
|
|
121
125
|
this.plan = null;
|
|
@@ -182,6 +186,8 @@ export class Session {
|
|
|
182
186
|
return { success: false, reason: "Invalid message structure" };
|
|
183
187
|
}
|
|
184
188
|
this.messages = state.messages;
|
|
189
|
+
this.unprunedMessages = [];
|
|
190
|
+
this.lastTools = [];
|
|
185
191
|
const validLazyToolNames = new Set(this.lazyTools.map((t) => t.name));
|
|
186
192
|
this.activatedLazyTools = new Set(
|
|
187
193
|
state.activatedLazyTools.filter((name) => validLazyToolNames.has(name))
|
|
@@ -273,6 +279,9 @@ export class Session {
|
|
|
273
279
|
let planRetryCount = 0;
|
|
274
280
|
let streamRetryCount = 0;
|
|
275
281
|
const MAX_STREAM_RETRIES = 1;
|
|
282
|
+
let lastToolCallKey = "";
|
|
283
|
+
let consecutiveIdenticalCalls = 0;
|
|
284
|
+
const MAX_IDENTICAL_CALLS = 2;
|
|
276
285
|
try {
|
|
277
286
|
while (true) {
|
|
278
287
|
if (this.abortController.signal.aborted) {
|
|
@@ -299,6 +308,7 @@ export class Session {
|
|
|
299
308
|
};
|
|
300
309
|
const serverToolDefs = serverTools.map((t) => buildDefinition(t, defCtx)).filter((d) => d !== null);
|
|
301
310
|
const allTools = [...serverToolDefs, ...this.tools, ...activatedTools];
|
|
311
|
+
this.lastTools = allTools;
|
|
302
312
|
const systemPrompt = buildSystemPrompt(
|
|
303
313
|
this.pageContext,
|
|
304
314
|
resolvedSkills,
|
|
@@ -326,7 +336,6 @@ export class Session {
|
|
|
326
336
|
}
|
|
327
337
|
switch (event.type) {
|
|
328
338
|
case "debug_request":
|
|
329
|
-
this.lastProviderTools = event.tools;
|
|
330
339
|
break;
|
|
331
340
|
case "text_start":
|
|
332
341
|
inTextBlock = true;
|
|
@@ -392,6 +401,25 @@ export class Session {
|
|
|
392
401
|
name: currentToolUse.name,
|
|
393
402
|
input
|
|
394
403
|
});
|
|
404
|
+
const toolCallKey = currentToolUse.name + ":" + currentToolUse.inputJson;
|
|
405
|
+
if (toolCallKey === lastToolCallKey) {
|
|
406
|
+
consecutiveIdenticalCalls++;
|
|
407
|
+
} else {
|
|
408
|
+
lastToolCallKey = toolCallKey;
|
|
409
|
+
consecutiveIdenticalCalls = 1;
|
|
410
|
+
}
|
|
411
|
+
if (consecutiveIdenticalCalls > MAX_IDENTICAL_CALLS) {
|
|
412
|
+
toolResults.push({
|
|
413
|
+
type: "tool_result",
|
|
414
|
+
tool_use_id: currentToolUse.id,
|
|
415
|
+
content: JSON.stringify({
|
|
416
|
+
error: `You have called "${currentToolUse.name}" ${consecutiveIdenticalCalls} times in a row with identical parameters and received the same result each time. Stop repeating this call. Use the information you already have or try a different approach.`
|
|
417
|
+
}),
|
|
418
|
+
is_error: true
|
|
419
|
+
});
|
|
420
|
+
currentToolUse = null;
|
|
421
|
+
break;
|
|
422
|
+
}
|
|
395
423
|
const matchedServerTool = serverTools.find(
|
|
396
424
|
(t) => t.name === currentToolUse.name
|
|
397
425
|
);
|
|
@@ -600,6 +628,7 @@ export class Session {
|
|
|
600
628
|
} finally {
|
|
601
629
|
this.isProcessing = false;
|
|
602
630
|
this.abortController = null;
|
|
631
|
+
this.unprunedMessages = structuredClone(this.messages);
|
|
603
632
|
pruneMessages(
|
|
604
633
|
this.messages,
|
|
605
634
|
KEEP_RECENT_TURNS,
|
|
@@ -674,61 +703,36 @@ export class Session {
|
|
|
674
703
|
return map;
|
|
675
704
|
}
|
|
676
705
|
buildTranscript() {
|
|
677
|
-
const
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
const lazyToolSummaries = this.lazyTools.map((t) => ({
|
|
706
|
+
const system = this.pageContext ? buildSystemPromptEntries(
|
|
707
|
+
this.pageContext,
|
|
708
|
+
resolveSkills(this.pageContext),
|
|
709
|
+
this.lazyTools.map((t) => ({
|
|
682
710
|
name: t.name,
|
|
683
711
|
description: t.description
|
|
684
|
-
}))
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
lines.push("TOOLS (exact payload sent to provider)");
|
|
700
|
-
lines.push("=".repeat(80));
|
|
701
|
-
lines.push(JSON.stringify(this.lastProviderTools, null, 2));
|
|
702
|
-
lines.push("");
|
|
703
|
-
}
|
|
704
|
-
for (const message of this.messages) {
|
|
705
|
-
lines.push("=".repeat(80));
|
|
706
|
-
lines.push(`${message.role.toUpperCase()}`);
|
|
707
|
-
lines.push("=".repeat(80));
|
|
708
|
-
if (typeof message.content === "string") {
|
|
709
|
-
lines.push(message.content);
|
|
710
|
-
} else if (Array.isArray(message.content)) {
|
|
711
|
-
for (const block of message.content) {
|
|
712
|
-
if (block.type === "text") {
|
|
713
|
-
lines.push(block.text);
|
|
714
|
-
} else if (block.type === "skill") {
|
|
715
|
-
lines.push(`[Skill: ${block.name}]`);
|
|
716
|
-
lines.push(block.text);
|
|
717
|
-
} else if (block.type === "tool_use") {
|
|
718
|
-
lines.push(`[Tool Call: ${block.name}]`);
|
|
719
|
-
lines.push(JSON.stringify(block.input, null, 2));
|
|
720
|
-
} else if (block.type === "tool_result") {
|
|
721
|
-
lines.push(`[Tool Result: ${block.tool_use_id}]`);
|
|
722
|
-
try {
|
|
723
|
-
lines.push(JSON.stringify(JSON.parse(block.content), null, 2));
|
|
724
|
-
} catch {
|
|
725
|
-
lines.push(block.content);
|
|
726
|
-
}
|
|
727
|
-
}
|
|
712
|
+
})),
|
|
713
|
+
this.getActivePlanContext(),
|
|
714
|
+
this.loadedSkills
|
|
715
|
+
) : [];
|
|
716
|
+
const messages = this.messages.map((msg, i) => {
|
|
717
|
+
const entry = {
|
|
718
|
+
type: msg.role === "assistant" ? "agent" : "user",
|
|
719
|
+
seen: msg.content
|
|
720
|
+
};
|
|
721
|
+
const unpruned = this.unprunedMessages[i];
|
|
722
|
+
if (unpruned) {
|
|
723
|
+
const seenJson = JSON.stringify(msg.content);
|
|
724
|
+
const fullJson = JSON.stringify(unpruned.content);
|
|
725
|
+
if (seenJson !== fullJson) {
|
|
726
|
+
entry.full = unpruned.content;
|
|
728
727
|
}
|
|
729
728
|
}
|
|
730
|
-
|
|
731
|
-
}
|
|
732
|
-
|
|
729
|
+
return entry;
|
|
730
|
+
});
|
|
731
|
+
const tools = this.lastTools.map((t) => ({
|
|
732
|
+
name: t.name,
|
|
733
|
+
description: t.description,
|
|
734
|
+
input_schema: t.input_schema
|
|
735
|
+
}));
|
|
736
|
+
return { system, messages, tools };
|
|
733
737
|
}
|
|
734
738
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PageContext } from '../shared/types.js';
|
|
1
|
+
import type { PageContext, TranscriptSystemPrompt } from '../shared/types.js';
|
|
2
2
|
import type { ResolvedSkill } from './skills/types.js';
|
|
3
3
|
import type { ActivePlanContext, SystemPromptBlock } from './system-prompts/types.js';
|
|
4
4
|
/**
|
|
@@ -20,3 +20,11 @@ export declare function buildSystemPromptText(context: PageContext, resolvedSkil
|
|
|
20
20
|
name: string;
|
|
21
21
|
description: string;
|
|
22
22
|
}[], activePlan?: ActivePlanContext, loadedSkills?: ReadonlySet<string>): string;
|
|
23
|
+
/**
|
|
24
|
+
* Build structured system prompt entries for the transcript.
|
|
25
|
+
* Returns one entry per prompt definition with id, name, and content.
|
|
26
|
+
*/
|
|
27
|
+
export declare function buildSystemPromptEntries(context: PageContext, resolvedSkills: ResolvedSkill[], lazyTools?: {
|
|
28
|
+
name: string;
|
|
29
|
+
description: string;
|
|
30
|
+
}[], activePlan?: ActivePlanContext, loadedSkills?: ReadonlySet<string>): TranscriptSystemPrompt[];
|
|
@@ -51,3 +51,29 @@ export function buildSystemPromptText(context, resolvedSkills, lazyTools = [], a
|
|
|
51
51
|
loadedSkills
|
|
52
52
|
).map((b) => b.text).join("\n\n");
|
|
53
53
|
}
|
|
54
|
+
export function buildSystemPromptEntries(context, resolvedSkills, lazyTools = [], activePlan, loadedSkills = /* @__PURE__ */ new Set()) {
|
|
55
|
+
const promptContext = {
|
|
56
|
+
pageContext: context,
|
|
57
|
+
resolvedSkills,
|
|
58
|
+
lazyTools,
|
|
59
|
+
isDebugMode: !!(import.meta.dev && debugPrompt),
|
|
60
|
+
activePlan,
|
|
61
|
+
loadedSkills
|
|
62
|
+
};
|
|
63
|
+
const sorted = systemPrompts.filter((sp) => !sp.modes?.length || sp.modes.includes(context.editMode)).sort((a, b) => {
|
|
64
|
+
const groupDiff = getCacheGroupOrder(a) - getCacheGroupOrder(b);
|
|
65
|
+
if (groupDiff !== 0) return groupDiff;
|
|
66
|
+
return a.weight - b.weight;
|
|
67
|
+
});
|
|
68
|
+
const entries = [];
|
|
69
|
+
for (const sp of sorted) {
|
|
70
|
+
const text = sp.getPrompt(promptContext)?.trim();
|
|
71
|
+
if (!text) continue;
|
|
72
|
+
entries.push({
|
|
73
|
+
id: sp.id,
|
|
74
|
+
name: sp.title,
|
|
75
|
+
content: text
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return entries;
|
|
79
|
+
}
|
|
@@ -204,6 +204,40 @@ export type UsageTurn = {
|
|
|
204
204
|
cacheReadInputTokens: number;
|
|
205
205
|
pricing: UsagePricing | null;
|
|
206
206
|
};
|
|
207
|
+
/**
|
|
208
|
+
* A single system prompt entry in the structured transcript.
|
|
209
|
+
*/
|
|
210
|
+
export type TranscriptSystemPrompt = {
|
|
211
|
+
id: string;
|
|
212
|
+
name: string;
|
|
213
|
+
content: string;
|
|
214
|
+
};
|
|
215
|
+
/**
|
|
216
|
+
* A single message in the structured transcript.
|
|
217
|
+
* `seen` is the pruned content actually sent to the LLM.
|
|
218
|
+
* `full` is the pre-pruned content, omitted when identical to `seen`.
|
|
219
|
+
*/
|
|
220
|
+
export type TranscriptMessage = {
|
|
221
|
+
type: 'agent' | 'user';
|
|
222
|
+
seen: string | GenericContentBlock[];
|
|
223
|
+
full?: string | GenericContentBlock[];
|
|
224
|
+
};
|
|
225
|
+
/**
|
|
226
|
+
* Tool definition as included in the transcript.
|
|
227
|
+
*/
|
|
228
|
+
export type TranscriptToolDefinition = {
|
|
229
|
+
name: string;
|
|
230
|
+
description: string;
|
|
231
|
+
input_schema: Record<string, unknown>;
|
|
232
|
+
};
|
|
233
|
+
/**
|
|
234
|
+
* Structured transcript of the current conversation state.
|
|
235
|
+
*/
|
|
236
|
+
export type Transcript = {
|
|
237
|
+
system: TranscriptSystemPrompt[];
|
|
238
|
+
messages: TranscriptMessage[];
|
|
239
|
+
tools: TranscriptToolDefinition[];
|
|
240
|
+
};
|
|
207
241
|
/**
|
|
208
242
|
* Tool definition sent from client to server on init.
|
|
209
243
|
*/
|
|
@@ -404,7 +438,7 @@ export type ServerMessage = {
|
|
|
404
438
|
retryable?: boolean;
|
|
405
439
|
} | {
|
|
406
440
|
type: 'transcript';
|
|
407
|
-
|
|
441
|
+
transcript: Transcript;
|
|
408
442
|
} | {
|
|
409
443
|
type: 'server_tool_result';
|
|
410
444
|
tool: 'load_skill' | 'load_tools' | 'create_plan' | 'complete_plan_step';
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { B as BlokkliModule } from '../../shared/editor.CWQIFIEQ.mjs';
|
|
2
|
+
import 'nuxt/schema';
|
|
3
|
+
import 'consola';
|
|
4
|
+
import '../../../dist/global/types/definitions.js';
|
|
5
|
+
import '../../../dist/global/types/theme.js';
|
|
6
|
+
import '@nuxt/kit';
|
|
7
|
+
import '../../../dist/global/types/features.js';
|
|
8
|
+
|
|
9
|
+
type ChartColor = {
|
|
10
|
+
/**
|
|
11
|
+
* A valid CSS color value, e.g. '#ff0000', 'rgb(255, 0, 0)',
|
|
12
|
+
* or 'rgb(var(--theme-color-primary))' for CSS custom properties.
|
|
13
|
+
*/
|
|
14
|
+
color: string;
|
|
15
|
+
/**
|
|
16
|
+
* The label of the color.
|
|
17
|
+
*/
|
|
18
|
+
label: string;
|
|
19
|
+
};
|
|
20
|
+
type ChartsModuleOptions = {
|
|
21
|
+
/**
|
|
22
|
+
* Provide the path to a custom component to render charts.
|
|
23
|
+
*
|
|
24
|
+
* @todo not yet implemented
|
|
25
|
+
*/
|
|
26
|
+
chartRenderComponent?: string;
|
|
27
|
+
/**
|
|
28
|
+
* The available chart colors.
|
|
29
|
+
*/
|
|
30
|
+
colors: Record<string, ChartColor>;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
declare const _default: (options: ChartsModuleOptions) => BlokkliModule<ChartsModuleOptions>;
|
|
34
|
+
|
|
35
|
+
export { _default as default };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { createResolver } from '@nuxt/kit';
|
|
2
|
+
import { d as defineBlokkliModule } from '../../shared/editor.CGf7C_0M.mjs';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { d as defineCodeTemplate } from '../../shared/editor.6D5vApr0.mjs';
|
|
5
|
+
|
|
6
|
+
function chartsConfigTemplate(options) {
|
|
7
|
+
return defineCodeTemplate(
|
|
8
|
+
"charts-config",
|
|
9
|
+
() => {
|
|
10
|
+
return `
|
|
11
|
+
export const COLORS = ${JSON.stringify(options.colors)}
|
|
12
|
+
`;
|
|
13
|
+
},
|
|
14
|
+
() => {
|
|
15
|
+
return `
|
|
16
|
+
import type { ChartColor } from '#blokkli/charts/types'
|
|
17
|
+
|
|
18
|
+
export const COLORS: Record<string, ChartColor>
|
|
19
|
+
`;
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const resolve = createResolver(
|
|
25
|
+
fileURLToPath(new URL("./", import.meta.url))
|
|
26
|
+
).resolve;
|
|
27
|
+
const index = defineBlokkliModule({
|
|
28
|
+
alterOptions(options) {
|
|
29
|
+
options.blokkliDirs ??= [];
|
|
30
|
+
options.blokkliDirs.push(resolve("./runtime/blokkli"));
|
|
31
|
+
},
|
|
32
|
+
setup(ctx, options) {
|
|
33
|
+
ctx.context.blocks.addFile(
|
|
34
|
+
resolve("./runtime/components/Fragment/BlokkliChart.vue")
|
|
35
|
+
);
|
|
36
|
+
ctx.context.features.addFile(resolve("./runtime/features/charts/index.vue"));
|
|
37
|
+
ctx.context.addFeatureFragment("blokkli_chart");
|
|
38
|
+
ctx.context.addTemplate(chartsConfigTemplate(options));
|
|
39
|
+
ctx.helper.addAlias("#blokkli/charts/types", resolve("./runtime/types"));
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export { index as default };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { defineBlokkliAgentSkill } from "#blokkli/agent/server/skills";
|
|
2
|
+
export default defineBlokkliAgentSkill({
|
|
3
|
+
name: "charts",
|
|
4
|
+
label: { en: "Working with charts", de: "Arbeiten mit Diagrammen" },
|
|
5
|
+
description: "How charts work in bl\xF6kkli. LOAD THIS when the user asks about charts or when you need to create or update a chart! Charts are a special blokkli_fragment.",
|
|
6
|
+
getContents: () => `
|
|
7
|
+
# Charts
|
|
8
|
+
|
|
9
|
+
Charts are implemented as **fragments** with the bundle "blokkli_fragment" and the fragment name "blokkli_chart". When you see a paragraph with bundle "blokkli_fragment" and fragmentName "blokkli_chart", that IS the chart paragraph.
|
|
10
|
+
|
|
11
|
+
## Key concept
|
|
12
|
+
|
|
13
|
+
The chart paragraph's UUID is what you pass directly to the chart tools. There is no separate "chart entity" inside the fragment \u2014 the fragment IS the chart.
|
|
14
|
+
|
|
15
|
+
## Available tools
|
|
16
|
+
|
|
17
|
+
- **get_chart_data**: Read the current chart data (type, categories, series, colors, typeOptions). Always call this first when modifying an existing chart!
|
|
18
|
+
- **create_chart**: Create a new chart. Requires chart data (type, categories, series).
|
|
19
|
+
- **update_chart**: Update an existing chart. Pass the fragment paragraph's UUID and only the properties you want to change (title, type, categories, series, categoryColors, footnotes, typeOptions).
|
|
20
|
+
- **get_chart_type_options**: Get available typeOptions for a chart type. Call this to discover which rendering options exist (e.g. stacked, horizontal for bar charts) before setting typeOptions.
|
|
21
|
+
|
|
22
|
+
## Workflow
|
|
23
|
+
|
|
24
|
+
1. To **read** a chart's current state: use get_chart_data with the paragraph UUID.
|
|
25
|
+
2. To **create** a chart: use create_chart with the data.
|
|
26
|
+
3. To **modify** a chart: first call get_chart_data to see the current state, then use update_chart with only the properties you want to change.
|
|
27
|
+
4. To **change rendering options** (e.g. stacked bars, smooth lines, grid lines): first call get_chart_type_options with the chart type to see available options, then use update_chart with the typeOptions property.
|
|
28
|
+
|
|
29
|
+
## Chart types
|
|
30
|
+
|
|
31
|
+
bar, line, pie, area, donut, heatmap, radialBar, radar.
|
|
32
|
+
|
|
33
|
+
- pie, donut, radialBar: Single-series charts where each category gets its own color (categoryColors).
|
|
34
|
+
- bar, line, area, heatmap, radar: Multi-series charts where each series has its own color.
|
|
35
|
+
|
|
36
|
+
Each chart type has different options!
|
|
37
|
+
|
|
38
|
+
## Colors
|
|
39
|
+
|
|
40
|
+
Series colors and category colors use color IDs defined in the project configuration. They are auto-assigned if omitted. The valid color IDs are part of the tool schemas (enum values).
|
|
41
|
+
`
|
|
42
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { BlokkliChartData, ChartColor } from '#blokkli/charts/types';
|
|
3
|
+
export declare const chartTypeEnum: z.ZodEnum<{
|
|
4
|
+
bar: "bar";
|
|
5
|
+
line: "line";
|
|
6
|
+
pie: "pie";
|
|
7
|
+
area: "area";
|
|
8
|
+
donut: "donut";
|
|
9
|
+
heatmap: "heatmap";
|
|
10
|
+
radialBar: "radialBar";
|
|
11
|
+
radar: "radar";
|
|
12
|
+
}>;
|
|
13
|
+
export declare const chartColorEnum: z.ZodEnum<{
|
|
14
|
+
[x: string]: string;
|
|
15
|
+
}>;
|
|
16
|
+
export declare const chartSeriesSchema: z.ZodObject<{
|
|
17
|
+
name: z.ZodString;
|
|
18
|
+
color: z.ZodOptional<z.ZodEnum<{
|
|
19
|
+
[x: string]: string;
|
|
20
|
+
}>>;
|
|
21
|
+
data: z.ZodArray<z.ZodNumber>;
|
|
22
|
+
}, z.core.$strip>;
|
|
23
|
+
export declare const chartDataSchema: z.ZodObject<{
|
|
24
|
+
title: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
25
|
+
type: z.ZodEnum<{
|
|
26
|
+
bar: "bar";
|
|
27
|
+
line: "line";
|
|
28
|
+
pie: "pie";
|
|
29
|
+
area: "area";
|
|
30
|
+
donut: "donut";
|
|
31
|
+
heatmap: "heatmap";
|
|
32
|
+
radialBar: "radialBar";
|
|
33
|
+
radar: "radar";
|
|
34
|
+
}>;
|
|
35
|
+
categories: z.ZodArray<z.ZodString>;
|
|
36
|
+
series: z.ZodArray<z.ZodObject<{
|
|
37
|
+
name: z.ZodString;
|
|
38
|
+
color: z.ZodOptional<z.ZodEnum<{
|
|
39
|
+
[x: string]: string;
|
|
40
|
+
}>>;
|
|
41
|
+
data: z.ZodArray<z.ZodNumber>;
|
|
42
|
+
}, z.core.$strip>>;
|
|
43
|
+
categoryColors: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
44
|
+
[x: string]: string;
|
|
45
|
+
}>>>;
|
|
46
|
+
footnotes: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
47
|
+
typeOptions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodBoolean, z.ZodNumber]>>>;
|
|
48
|
+
}, z.core.$strip>;
|
|
49
|
+
/**
|
|
50
|
+
* Validate and normalize chart data.
|
|
51
|
+
*
|
|
52
|
+
* - Checks series data length matches categories length
|
|
53
|
+
* - Auto-assigns missing series colors
|
|
54
|
+
* - Auto-assigns categoryColors for pie/donut/radialBar
|
|
55
|
+
* - Validates color IDs exist in the provided colors map
|
|
56
|
+
* - Validates typeOptions keys against the chart type definition
|
|
57
|
+
* - Fills typeOptions defaults
|
|
58
|
+
*/
|
|
59
|
+
export declare function validateChartData(data: BlokkliChartData, colors: Record<string, ChartColor>): {
|
|
60
|
+
error: string;
|
|
61
|
+
} | {
|
|
62
|
+
data: BlokkliChartData;
|
|
63
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { getColorIdAtIndex } from "#blokkli/charts/types";
|
|
3
|
+
import { getChartTypeRuntime, getDefaultTypeOptions } from "../../chartTypes/index.js";
|
|
4
|
+
import { COLORS } from "#blokkli-build/charts-config";
|
|
5
|
+
const SINGLE_SERIES_TYPES = ["pie", "donut", "radialBar"];
|
|
6
|
+
export const chartTypeEnum = z.enum([
|
|
7
|
+
"bar",
|
|
8
|
+
"line",
|
|
9
|
+
"pie",
|
|
10
|
+
"area",
|
|
11
|
+
"donut",
|
|
12
|
+
"heatmap",
|
|
13
|
+
"radialBar",
|
|
14
|
+
"radar"
|
|
15
|
+
]);
|
|
16
|
+
const colorIds = Object.keys(COLORS);
|
|
17
|
+
export const chartColorEnum = z.enum(colorIds);
|
|
18
|
+
export const chartSeriesSchema = z.object({
|
|
19
|
+
name: z.string().describe("Series name (shown in legend)"),
|
|
20
|
+
color: chartColorEnum.optional().describe(
|
|
21
|
+
"Color ID from available chart colors. Auto-assigned if omitted."
|
|
22
|
+
),
|
|
23
|
+
data: z.array(z.number()).describe("Data values, one per category")
|
|
24
|
+
});
|
|
25
|
+
export const chartDataSchema = z.object({
|
|
26
|
+
title: z.string().optional().default("").describe("Chart title"),
|
|
27
|
+
type: chartTypeEnum.describe("Chart type"),
|
|
28
|
+
categories: z.array(z.string()).min(1).describe("Category labels (x-axis or slice names)"),
|
|
29
|
+
series: z.array(chartSeriesSchema).min(1).describe("Data series"),
|
|
30
|
+
categoryColors: z.array(chartColorEnum).optional().describe(
|
|
31
|
+
"Color IDs per category (for pie/donut/radialBar). Auto-assigned if omitted."
|
|
32
|
+
),
|
|
33
|
+
footnotes: z.array(z.string()).optional().default([]).describe(
|
|
34
|
+
"Footnote texts. Reference in categories/series names as {1}, {2}, etc."
|
|
35
|
+
),
|
|
36
|
+
typeOptions: z.record(z.string(), z.union([z.string(), z.boolean(), z.number()])).optional().describe(
|
|
37
|
+
"Type-specific rendering options. Use get_chart_type_options to see available keys."
|
|
38
|
+
)
|
|
39
|
+
});
|
|
40
|
+
export function validateChartData(data, colors) {
|
|
41
|
+
const colorIds2 = Object.keys(colors);
|
|
42
|
+
for (let i = 0; i < data.series.length; i++) {
|
|
43
|
+
const series = data.series[i];
|
|
44
|
+
if (series.data.length !== data.categories.length) {
|
|
45
|
+
return {
|
|
46
|
+
error: `Series "${series.name}" has ${series.data.length} data values but there are ${data.categories.length} categories. Each series must have exactly one value per category.`
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
for (let i = 0; i < data.series.length; i++) {
|
|
51
|
+
const series = data.series[i];
|
|
52
|
+
if (!series.color) {
|
|
53
|
+
series.color = getColorIdAtIndex(i, colors);
|
|
54
|
+
} else if (!colors[series.color]) {
|
|
55
|
+
return {
|
|
56
|
+
error: `Invalid color ID "${series.color}" on series "${series.name}". Available colors: ${colorIds2.join(", ")}`
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const isSingleSeries = SINGLE_SERIES_TYPES.includes(data.type);
|
|
61
|
+
if (isSingleSeries) {
|
|
62
|
+
if (!data.categoryColors || data.categoryColors.length !== data.categories.length) {
|
|
63
|
+
data.categoryColors = data.categories.map(
|
|
64
|
+
(_, i) => getColorIdAtIndex(i, colors)
|
|
65
|
+
);
|
|
66
|
+
} else {
|
|
67
|
+
for (let i = 0; i < data.categoryColors.length; i++) {
|
|
68
|
+
const id = data.categoryColors[i];
|
|
69
|
+
if (!colors[id]) {
|
|
70
|
+
return {
|
|
71
|
+
error: `Invalid categoryColor ID "${id}" at index ${i}. Available colors: ${colorIds2.join(", ")}`
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
} else if (!data.categoryColors || data.categoryColors.length !== data.categories.length) {
|
|
77
|
+
data.categoryColors = data.categories.map(
|
|
78
|
+
(_, i) => getColorIdAtIndex(i, colors)
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
const defaults = getDefaultTypeOptions(data.type);
|
|
82
|
+
const typeDef = getChartTypeRuntime(data.type);
|
|
83
|
+
if (data.typeOptions && typeDef) {
|
|
84
|
+
for (const key of Object.keys(data.typeOptions)) {
|
|
85
|
+
if (!(key in typeDef.editor.options)) {
|
|
86
|
+
const availableKeys = Object.keys(typeDef.editor.options);
|
|
87
|
+
return {
|
|
88
|
+
error: `Invalid typeOption "${key}" for chart type "${data.type}". Available options: ${availableKeys.join(", ")}`
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
data.typeOptions = { ...defaults, ...data.typeOptions || {} };
|
|
94
|
+
if (!data.footnotes) {
|
|
95
|
+
data.footnotes = [];
|
|
96
|
+
}
|
|
97
|
+
return { data };
|
|
98
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { defineBlokkliAgentTool } from "#blokkli/agent/app/composables";
|
|
3
|
+
import {
|
|
4
|
+
mutationResultSchema,
|
|
5
|
+
parentSchema,
|
|
6
|
+
positionSchema,
|
|
7
|
+
resolvePosition
|
|
8
|
+
} from "#blokkli/agent/app/tools/schemas";
|
|
9
|
+
import { chartDataSchema, validateChartData } from "../chart_schemas.js";
|
|
10
|
+
import { COLORS } from "#blokkli-build/charts-config";
|
|
11
|
+
const paramsSchema = z.object({
|
|
12
|
+
chart: chartDataSchema,
|
|
13
|
+
parent: parentSchema.describe("The parent entity to add the chart to"),
|
|
14
|
+
position: positionSchema
|
|
15
|
+
});
|
|
16
|
+
export default defineBlokkliAgentTool({
|
|
17
|
+
name: "create_chart",
|
|
18
|
+
description: "Create a new chart on the page. Series colors are auto-assigned if omitted. For pie/donut/radialBar charts, only the first series is used and each category gets its own color (auto-assigned if categoryColors is omitted). Use get_chart_type_options to discover available typeOptions for the chosen chart type before setting them.",
|
|
19
|
+
category: "mutation",
|
|
20
|
+
prunedSummary: (r) => r.success ? "created chart" : "rejected",
|
|
21
|
+
modes: ["editing"],
|
|
22
|
+
lazy: true,
|
|
23
|
+
label($t) {
|
|
24
|
+
return $t("aiAgentCreateChartRunning", "Creating chart...");
|
|
25
|
+
},
|
|
26
|
+
paramsSchema,
|
|
27
|
+
resultSchema: mutationResultSchema,
|
|
28
|
+
requiredAdapterMethods: ["fragmentsAddBlock"],
|
|
29
|
+
execute(ctx, params) {
|
|
30
|
+
const { fields, definitions } = ctx.app;
|
|
31
|
+
const fragment = definitions.fragmentDefinitions.value.find(
|
|
32
|
+
(f) => f.name === "blokkli_chart"
|
|
33
|
+
);
|
|
34
|
+
if (!fragment) {
|
|
35
|
+
return { error: 'Chart fragment "blokkli_chart" is not available.' };
|
|
36
|
+
}
|
|
37
|
+
const field = fields.find(params.parent.uuid, params.parent.field);
|
|
38
|
+
if (!field) {
|
|
39
|
+
return {
|
|
40
|
+
error: `Field not found: ${params.parent.field} on entity ${params.parent.uuid}`
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
if (!field.allowedFragments.includes("blokkli_chart")) {
|
|
44
|
+
return {
|
|
45
|
+
error: `Field "${params.parent.field}" does not allow the "blokkli_chart" fragment. Allowed fragments: ${field.allowedFragments.length ? field.allowedFragments.join(", ") : "none"}`
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const chartData = {
|
|
49
|
+
title: params.chart.title,
|
|
50
|
+
type: params.chart.type,
|
|
51
|
+
categories: params.chart.categories,
|
|
52
|
+
series: params.chart.series.map((s) => ({
|
|
53
|
+
name: s.name,
|
|
54
|
+
color: s.color || "",
|
|
55
|
+
data: s.data
|
|
56
|
+
})),
|
|
57
|
+
categoryColors: params.chart.categoryColors || [],
|
|
58
|
+
footnotes: params.chart.footnotes,
|
|
59
|
+
typeOptions: params.chart.typeOptions || {}
|
|
60
|
+
};
|
|
61
|
+
const result = validateChartData(chartData, COLORS);
|
|
62
|
+
if ("error" in result) return result;
|
|
63
|
+
const resolved = resolvePosition(
|
|
64
|
+
ctx.app,
|
|
65
|
+
params.parent.uuid,
|
|
66
|
+
params.parent.field,
|
|
67
|
+
params.position
|
|
68
|
+
);
|
|
69
|
+
if ("error" in resolved) return resolved;
|
|
70
|
+
const { $t } = ctx.app;
|
|
71
|
+
return {
|
|
72
|
+
type: "add",
|
|
73
|
+
label: $t("aiAgentCreateChartDone", "Added chart"),
|
|
74
|
+
apply: (adapter) => adapter.fragmentsAddBlock({
|
|
75
|
+
name: "blokkli_chart",
|
|
76
|
+
host: {
|
|
77
|
+
type: params.parent.type,
|
|
78
|
+
uuid: params.parent.uuid,
|
|
79
|
+
fieldName: params.parent.field
|
|
80
|
+
},
|
|
81
|
+
preceedingUuid: resolved.afterUuid,
|
|
82
|
+
options: { data: JSON.stringify(result.data) }
|
|
83
|
+
})
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
});
|