@blokkli/editor 2.0.0-alpha.56 → 2.0.0-alpha.58

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/dist/module.d.mts +2 -2
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +2 -2
  4. package/dist/modules/agent/index.d.mts +1 -1
  5. package/dist/modules/agent/index.mjs +19 -19
  6. package/dist/modules/agent/runtime/app/composables/index.d.ts +3 -1
  7. package/dist/modules/agent/runtime/app/composables/index.js +1 -0
  8. package/dist/modules/agent/runtime/app/composables/useAgent.d.ts +6 -0
  9. package/dist/modules/agent/runtime/app/composables/useAgent.js +11 -0
  10. package/dist/modules/agent/runtime/app/features/agent/Container.vue +83 -88
  11. package/dist/modules/agent/runtime/app/helpers/buildPageContext.d.ts +7 -0
  12. package/dist/modules/agent/runtime/app/helpers/buildPageContext.js +81 -0
  13. package/dist/modules/agent/runtime/app/helpers/index.d.ts +15 -1
  14. package/dist/modules/agent/runtime/app/helpers/index.js +16 -0
  15. package/dist/modules/agent/runtime/app/helpers/injections.d.ts +3 -0
  16. package/dist/modules/agent/runtime/app/helpers/injections.js +3 -0
  17. package/dist/modules/agent/runtime/app/providers/agentProvider.d.ts +33 -0
  18. package/dist/modules/agent/runtime/app/providers/agentProvider.js +315 -0
  19. package/dist/modules/agent/runtime/app/providers/conversationProvider.d.ts +50 -0
  20. package/dist/modules/agent/runtime/app/providers/conversationProvider.js +263 -0
  21. package/dist/modules/agent/runtime/app/providers/planProvider.d.ts +15 -0
  22. package/dist/modules/agent/runtime/app/providers/planProvider.js +34 -0
  23. package/dist/modules/agent/runtime/app/providers/socketProvider.d.ts +17 -0
  24. package/dist/modules/agent/runtime/app/providers/socketProvider.js +110 -0
  25. package/dist/modules/agent/runtime/app/providers/toolsProvider.d.ts +44 -0
  26. package/dist/modules/agent/runtime/app/providers/toolsProvider.js +298 -0
  27. package/dist/modules/agent/runtime/app/types/index.d.ts +47 -0
  28. package/dist/modules/agent/runtime/app/types/index.js +3 -1
  29. package/dist/modules/agent/runtime/server/helpers.js +2 -1
  30. package/dist/modules/charts/index.d.mts +1 -1
  31. package/dist/modules/drupal/index.d.mts +2 -2
  32. package/dist/modules/iframes/index.d.mts +1 -1
  33. package/dist/modules/index.d.mts +1 -1
  34. package/dist/modules/readability/index.d.mts +2 -2
  35. package/dist/modules/table-of-contents/index.d.mts +2 -2
  36. package/dist/runtime/editor/components/DiffViewer/State.vue +51 -67
  37. package/dist/runtime/editor/components/EditProvider.vue +30 -10
  38. package/dist/runtime/editor/components/PreviewProvider.vue +14 -8
  39. package/dist/runtime/editor/css/output.css +1 -1
  40. package/dist/runtime/editor/events/index.d.ts +4 -3
  41. package/dist/runtime/editor/features/add-list/index.vue +2 -1
  42. package/dist/runtime/editor/features/changelog/changelog.json +8 -0
  43. package/dist/runtime/editor/features/dev-mode/index.vue +1 -10
  44. package/dist/runtime/editor/features/responsive-preview/Frame/index.vue +2 -2
  45. package/dist/runtime/editor/features/translations/index.vue +1 -0
  46. package/dist/runtime/editor/plugins/Sidebar/index.vue +9 -2
  47. package/dist/runtime/editor/providers/state.js +4 -1
  48. package/dist/shared/{editor.BTOBvmaz.d.mts → editor.Bpw1EP57.d.mts} +3 -3
  49. package/dist/shared/{editor.9vf8ZnOp.mjs → editor.FygP6XeF.mjs} +2 -2
  50. package/dist/types.d.mts +1 -1
  51. package/package.json +30 -7
  52. package/dist/modules/agent/runtime/app/composables/agentProvider.d.ts +0 -62
  53. package/dist/modules/agent/runtime/app/composables/agentProvider.js +0 -1048
@@ -0,0 +1,110 @@
1
+ import { ref, readonly } from "#imports";
2
+ import { routeAgent } from "#blokkli-build/agent-client";
3
+ const PING_INTERVAL_MS = 3e4;
4
+ const RECONNECT_DELAY_MS = 3e3;
5
+ const MAX_RECONNECT_ATTEMPTS = 10;
6
+ export default function socketProvider() {
7
+ let ws = null;
8
+ let pingInterval = null;
9
+ let reconnectTimeout = null;
10
+ let reconnectAttempts = 0;
11
+ const isConnected = ref(false);
12
+ let messageHandler = null;
13
+ let lifecycle = {};
14
+ function setMessageHandler(handler) {
15
+ messageHandler = handler;
16
+ }
17
+ function setLifecycleHandlers(handlers) {
18
+ lifecycle = handlers;
19
+ }
20
+ function send(message) {
21
+ if (ws?.readyState === WebSocket.OPEN) {
22
+ ws.send(JSON.stringify(message));
23
+ }
24
+ }
25
+ function detachListeners(socket) {
26
+ socket.removeEventListener("open", onWebSocketOpen);
27
+ socket.removeEventListener("close", onWebSocketClose);
28
+ socket.removeEventListener("error", onWebSocketError);
29
+ socket.removeEventListener("message", onWebSocketMessage);
30
+ }
31
+ function clearTimers() {
32
+ if (pingInterval) {
33
+ window.clearInterval(pingInterval);
34
+ pingInterval = null;
35
+ }
36
+ if (reconnectTimeout) {
37
+ window.clearTimeout(reconnectTimeout);
38
+ reconnectTimeout = null;
39
+ }
40
+ }
41
+ function onWebSocketOpen() {
42
+ isConnected.value = true;
43
+ reconnectAttempts = 0;
44
+ pingInterval = window.setInterval(() => {
45
+ send({ type: "ping" });
46
+ }, PING_INTERVAL_MS);
47
+ lifecycle.onOpen?.();
48
+ }
49
+ function onWebSocketClose() {
50
+ if (pingInterval) {
51
+ window.clearInterval(pingInterval);
52
+ pingInterval = null;
53
+ }
54
+ isConnected.value = false;
55
+ lifecycle.onClose?.();
56
+ reconnectAttempts++;
57
+ if (reconnectAttempts > MAX_RECONNECT_ATTEMPTS) {
58
+ lifecycle.onMaxReconnects?.();
59
+ return;
60
+ }
61
+ reconnectTimeout = window.setTimeout(() => {
62
+ if (!isConnected.value) connect();
63
+ }, RECONNECT_DELAY_MS);
64
+ }
65
+ function onWebSocketError(error) {
66
+ console.error("WebSocket error:", error);
67
+ lifecycle.onError?.(error);
68
+ }
69
+ function onWebSocketMessage(event) {
70
+ try {
71
+ const data = JSON.parse(event.data);
72
+ messageHandler?.(data);
73
+ } catch (error) {
74
+ console.error("Failed to parse WebSocket message:", error);
75
+ }
76
+ }
77
+ function connect() {
78
+ if (ws && (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING)) {
79
+ return;
80
+ }
81
+ if (ws) {
82
+ detachListeners(ws);
83
+ ws = null;
84
+ }
85
+ const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
86
+ const url = `${protocol}//${window.location.host}${routeAgent}`;
87
+ ws = new WebSocket(url);
88
+ ws.addEventListener("open", onWebSocketOpen);
89
+ ws.addEventListener("close", onWebSocketClose);
90
+ ws.addEventListener("error", onWebSocketError);
91
+ ws.addEventListener("message", onWebSocketMessage);
92
+ }
93
+ function disconnect() {
94
+ clearTimers();
95
+ if (ws) {
96
+ detachListeners(ws);
97
+ ws.close();
98
+ ws = null;
99
+ }
100
+ isConnected.value = false;
101
+ }
102
+ return {
103
+ isConnected: readonly(isConnected),
104
+ send,
105
+ connect,
106
+ disconnect,
107
+ setMessageHandler,
108
+ setLifecycleHandlers
109
+ };
110
+ }
@@ -0,0 +1,44 @@
1
+ import { type Ref } from '#imports';
2
+ import type { MutationAction } from '#blokkli/agent/app/types';
3
+ import type { PageContext } from '#blokkli/agent/shared/types';
4
+ import type { BlokkliApp } from '#blokkli/editor/types/app';
5
+ import type { FullBlokkliAdapter } from '#blokkli/editor/adapter';
6
+ import type { AgentToolName, AgentToolMap } from '#blokkli-build/agent-client';
7
+ import type { SocketProvider } from './socketProvider.js';
8
+ import type { ConversationProvider } from './conversationProvider.js';
9
+ export type PendingMutationState = {
10
+ action: MutationAction;
11
+ resolve: (approved: boolean) => void;
12
+ };
13
+ export type PendingToolCall = {
14
+ toolName: string;
15
+ params: Record<string, unknown>;
16
+ };
17
+ export type ToolsProvider = {
18
+ pendingMutation: Ref<PendingMutationState | null>;
19
+ pendingToolCall: Ref<PendingToolCall | null>;
20
+ autoApprove: Ref<boolean>;
21
+ pageContext: Readonly<Ref<PageContext | null>>;
22
+ init: () => Promise<{
23
+ toolNames: string[];
24
+ }>;
25
+ setPageContext: (ctx: PageContext) => void;
26
+ dispatch: (callId: string, tool: string, params: Record<string, unknown>) => Promise<void>;
27
+ runForPrompt: <T extends AgentToolName>(toolName: T, params: AgentToolMap[T]['params']) => Promise<{
28
+ toolName: T;
29
+ params: AgentToolMap[T]['params'];
30
+ result: AgentToolMap[T]['result'];
31
+ label: string;
32
+ }>;
33
+ approve: () => void;
34
+ reject: () => void;
35
+ setAutoApprove: (value: boolean) => void;
36
+ onComponentDone: (result: unknown) => void;
37
+ cancelPending: () => void;
38
+ };
39
+ export default function toolsProvider({ app, adapter, socket, conversation, }: {
40
+ app: BlokkliApp;
41
+ adapter: FullBlokkliAdapter<any>;
42
+ socket: SocketProvider;
43
+ conversation: ConversationProvider;
44
+ }): ToolsProvider;
@@ -0,0 +1,298 @@
1
+ import { ref, shallowRef, readonly } from "#imports";
2
+ import {
3
+ createToolMap,
4
+ executeTool,
5
+ getToolCategory,
6
+ getToolDefinition,
7
+ getToolInfoForServer,
8
+ isMutationAction,
9
+ isQueryResult,
10
+ isToolError,
11
+ resolveTools,
12
+ asRecord,
13
+ splitMeta
14
+ } from "#blokkli/agent/app/helpers";
15
+ import { mcpTools } from "#blokkli-build/agent-client";
16
+ import { itemEntityType } from "#blokkli-build/config";
17
+ function generateId() {
18
+ return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
19
+ }
20
+ export default function toolsProvider({
21
+ app,
22
+ adapter,
23
+ socket,
24
+ conversation
25
+ }) {
26
+ const { $t, state } = app;
27
+ const pendingMutation = ref(null);
28
+ const pendingToolCall = ref(null);
29
+ const autoApprove = ref(false);
30
+ const pageContext = shallowRef(null);
31
+ let toolMap = {};
32
+ let pendingToolCallResolve = null;
33
+ function createToolContext() {
34
+ return {
35
+ app,
36
+ itemEntityType,
37
+ adapter,
38
+ pageContext: pageContext.value
39
+ };
40
+ }
41
+ async function init() {
42
+ const ctx = createToolContext();
43
+ const resolved = await resolveTools(mcpTools, ctx);
44
+ toolMap = createToolMap(resolved);
45
+ const toolNames = await getToolInfoForServer(
46
+ resolved,
47
+ state.editMode.value,
48
+ app,
49
+ adapter
50
+ );
51
+ return { toolNames };
52
+ }
53
+ function setPageContext(ctx) {
54
+ pageContext.value = ctx;
55
+ }
56
+ function waitForToolComponent(toolName, params) {
57
+ return new Promise((resolve) => {
58
+ pendingToolCall.value = { toolName, params };
59
+ pendingToolCallResolve = resolve;
60
+ });
61
+ }
62
+ function waitForApproval(action) {
63
+ return new Promise((resolve) => {
64
+ pendingMutation.value = { action, resolve };
65
+ });
66
+ }
67
+ async function executeLocally(toolName, params, setLabel) {
68
+ const ctx = createToolContext();
69
+ const toolDef = getToolDefinition(toolMap, toolName);
70
+ if (toolDef.component) {
71
+ const preparedParams = await executeTool(toolMap, toolName, ctx, params);
72
+ if (isToolError(preparedParams)) {
73
+ return { ok: false, error: preparedParams.error };
74
+ }
75
+ const raw = await waitForToolComponent(
76
+ toolDef.name,
77
+ preparedParams
78
+ );
79
+ const { payload, meta } = splitMeta(raw);
80
+ const payloadObj = asRecord(payload);
81
+ if (setLabel && payloadObj && typeof payloadObj.label === "string") {
82
+ setLabel(payloadObj.label);
83
+ }
84
+ return { ok: true, result: payload, meta };
85
+ }
86
+ const category = getToolCategory(toolMap, toolName);
87
+ const result = await executeTool(toolMap, toolName, ctx, params);
88
+ if (isToolError(result)) return { ok: false, error: result.error };
89
+ if (category === "query") {
90
+ if (isQueryResult(result)) {
91
+ if (setLabel) setLabel(result.label);
92
+ if (result.affectedUuids?.length) {
93
+ app.eventBus.emit("select", result.affectedUuids);
94
+ app.eventBus.emit("scrollSelectionIntoView", {});
95
+ }
96
+ return { ok: true, result: result.result, meta: {} };
97
+ }
98
+ return { ok: true, result, meta: {} };
99
+ }
100
+ if (!isMutationAction(result)) {
101
+ return { ok: false, error: "Invalid mutation tool result" };
102
+ }
103
+ const action = result;
104
+ if (setLabel) setLabel(action.label);
105
+ async function applyMutation() {
106
+ const uuidsBefore = state.getAllUuids();
107
+ await state.mutateWithLoadingState(() => action.apply(adapter));
108
+ const newUuids = state.getAllUuids().filter((uuid) => !uuidsBefore.includes(uuid));
109
+ const selectUuids = newUuids.length ? newUuids : action.affectedUuids || [];
110
+ if (selectUuids.length) {
111
+ app.eventBus.emit("select", selectUuids);
112
+ app.eventBus.emit("scrollSelectionIntoView", {});
113
+ }
114
+ return newUuids;
115
+ }
116
+ function buildMutationResult(newUuids) {
117
+ const newParagraphs = action.type === "add" && newUuids.length ? newUuids.map((uuid) => {
118
+ const block = app.blocks.getBlock(uuid);
119
+ if (!block) return null;
120
+ const blockFieldNames = app.types.fieldConfig.forEntityTypeAndBundle(itemEntityType, block.bundle).map((f) => f.name);
121
+ return {
122
+ uuid,
123
+ bundle: block.bundle,
124
+ ...blockFieldNames.length ? { paragraphFields: blockFieldNames } : {}
125
+ };
126
+ }).filter(
127
+ (b) => b !== null
128
+ ) : void 0;
129
+ return {
130
+ success: true,
131
+ historyIndex: state.currentMutationIndex.value,
132
+ newParagraphs: newParagraphs?.length ? newParagraphs : void 0,
133
+ ...action.result
134
+ };
135
+ }
136
+ if (autoApprove.value || !toolDef.requiresApproval) {
137
+ const newUuids = await applyMutation();
138
+ return { ok: true, result: buildMutationResult(newUuids), meta: {} };
139
+ }
140
+ const approved = await waitForApproval(action);
141
+ if (approved) {
142
+ const newUuids = await applyMutation();
143
+ return { ok: true, result: buildMutationResult(newUuids), meta: {} };
144
+ }
145
+ if (action.revert) action.revert();
146
+ return { ok: true, result: { success: false, rejected: true }, meta: {} };
147
+ }
148
+ async function dispatch(callId, tool, params) {
149
+ const toolDef = getToolDefinition(toolMap, tool);
150
+ const initialLabel = toolDef.label($t);
151
+ const toolId = generateId();
152
+ const timestamp = Date.now();
153
+ let currentLabel = initialLabel;
154
+ conversation.setActive({
155
+ type: "tool",
156
+ id: toolId,
157
+ callId,
158
+ tool,
159
+ label: initialLabel,
160
+ status: "active",
161
+ timestamp
162
+ });
163
+ function finishItem(status) {
164
+ conversation.pushTool({
165
+ type: "tool",
166
+ id: toolId,
167
+ callId,
168
+ tool,
169
+ label: currentLabel,
170
+ status,
171
+ timestamp
172
+ });
173
+ conversation.setActive(null);
174
+ }
175
+ try {
176
+ const outcome = await executeLocally(tool, params, (label) => {
177
+ currentLabel = label;
178
+ const active = conversation.activeItem.value;
179
+ if (active?.type === "tool" && active.callId === callId) {
180
+ conversation.setActive({ ...active, label });
181
+ }
182
+ });
183
+ if (!outcome.ok) {
184
+ finishItem("error");
185
+ socket.send({
186
+ type: "tool_result",
187
+ callId,
188
+ result: null,
189
+ error: outcome.error
190
+ });
191
+ return;
192
+ }
193
+ finishItem("success");
194
+ if (toolDef.buildDetails) {
195
+ try {
196
+ const detailsSource = outcome.meta.details ?? outcome.result;
197
+ const details = toolDef.buildDetails(detailsSource);
198
+ if (details != null) {
199
+ conversation.setToolDetail(callId, details);
200
+ }
201
+ } catch {
202
+ }
203
+ }
204
+ if (outcome.meta.usage) {
205
+ conversation.pushUsage(outcome.meta.usage);
206
+ }
207
+ let resultForServer = outcome.result;
208
+ const resultObj = asRecord(resultForServer);
209
+ if (toolDef.prunedSummary && resultObj) {
210
+ try {
211
+ const summary = toolDef.prunedSummary(resultObj);
212
+ if (summary) {
213
+ resultForServer = { ...resultObj, _summary: summary };
214
+ }
215
+ } catch {
216
+ }
217
+ }
218
+ socket.send({
219
+ type: "tool_result",
220
+ callId,
221
+ result: resultForServer,
222
+ skipLlmResponse: outcome.meta.skipLlmResponse
223
+ });
224
+ } catch (error) {
225
+ finishItem("error");
226
+ socket.send({
227
+ type: "tool_result",
228
+ callId,
229
+ result: null,
230
+ error: error.message
231
+ });
232
+ }
233
+ }
234
+ async function runForPrompt(toolName, params) {
235
+ const ctx = createToolContext();
236
+ if (!Object.keys(toolMap).length) {
237
+ const resolved = await resolveTools(mcpTools, ctx);
238
+ toolMap = createToolMap(resolved);
239
+ }
240
+ const toolDef = getToolDefinition(toolMap, toolName);
241
+ const rawResult = await executeTool(toolMap, toolName, ctx, params);
242
+ const label = isQueryResult(rawResult) ? rawResult.label : toolDef.label($t);
243
+ const result = isQueryResult(rawResult) ? rawResult.result : rawResult;
244
+ return { toolName, params, result, label };
245
+ }
246
+ function approve() {
247
+ if (pendingMutation.value) {
248
+ pendingMutation.value.resolve(true);
249
+ pendingMutation.value = null;
250
+ }
251
+ }
252
+ function reject() {
253
+ if (pendingMutation.value) {
254
+ pendingMutation.value.resolve(false);
255
+ pendingMutation.value = null;
256
+ }
257
+ }
258
+ function setAutoApprove(value) {
259
+ autoApprove.value = value;
260
+ if (value) approve();
261
+ }
262
+ function onComponentDone(result) {
263
+ if (pendingToolCallResolve) {
264
+ pendingToolCallResolve(result);
265
+ pendingToolCallResolve = null;
266
+ }
267
+ pendingToolCall.value = null;
268
+ }
269
+ function cancelPending() {
270
+ if (pendingMutation.value) {
271
+ if (pendingMutation.value.action.revert) {
272
+ pendingMutation.value.action.revert();
273
+ }
274
+ pendingMutation.value.resolve(false);
275
+ pendingMutation.value = null;
276
+ }
277
+ if (pendingToolCallResolve) {
278
+ pendingToolCallResolve({ cancelled: true });
279
+ pendingToolCallResolve = null;
280
+ }
281
+ pendingToolCall.value = null;
282
+ }
283
+ return {
284
+ pendingMutation,
285
+ pendingToolCall,
286
+ autoApprove,
287
+ pageContext: readonly(pageContext),
288
+ init,
289
+ setPageContext,
290
+ dispatch,
291
+ runForPrompt,
292
+ approve,
293
+ reject,
294
+ setAutoApprove,
295
+ onComponentDone,
296
+ cancelPending
297
+ };
298
+ }
@@ -1,6 +1,7 @@
1
1
  import type { BlokkliApp } from '#blokkli/editor/types/app';
2
2
  import type { FullBlokkliAdapter, MutationResponseLike, AdapterMethods } from '#blokkli/editor/adapter';
3
3
  import type { EditMode } from '#blokkli/editor/types/state';
4
+ import { type UsageTurn } from '#blokkli/agent/shared/types';
4
5
  import { z } from 'zod';
5
6
  import type { Component } from 'vue';
6
7
  import type { AgentToolName, AgentSkillName, AgentToolMap } from '#blokkli-build/agent-client';
@@ -55,6 +56,52 @@ export type QueryResult<T = unknown> = {
55
56
  export type ToolError = {
56
57
  error: string;
57
58
  };
59
+ /**
60
+ * Side-channel data that interactive tool components can attach to their
61
+ * emitted result alongside the LLM-facing payload. The provider strips
62
+ * these underscore-prefixed properties at the boundary so they never reach
63
+ * the server: `details` feeds `buildDetails()`, `usage` is folded into the
64
+ * conversation usage display, and `skipLlmResponse` ends the agent loop
65
+ * without an LLM reply when the user fully accepted the changes.
66
+ */
67
+ export type ToolMeta = {
68
+ details?: unknown;
69
+ usage?: UsageTurn;
70
+ skipLlmResponse?: boolean;
71
+ };
72
+ /**
73
+ * Shape an interactive tool component emits: the LLM-facing payload merged
74
+ * with optional side-channel metadata. Components can use this to type
75
+ * their `emit('done', ...)` payloads in a single place.
76
+ */
77
+ export type ComponentToolResult<T = Record<string, unknown>> = T & {
78
+ _details?: ToolMeta['details'];
79
+ _usage?: ToolMeta['usage'];
80
+ _skipLlmResponse?: ToolMeta['skipLlmResponse'];
81
+ };
82
+ /**
83
+ * Discriminated outcome returned by `executeToolLocally`. Callers branch
84
+ * on `ok` instead of runtime-checking the shape of an `unknown` result.
85
+ */
86
+ export type ToolOutcome = {
87
+ ok: false;
88
+ error: string;
89
+ } | {
90
+ ok: true;
91
+ result: unknown;
92
+ meta: ToolMeta;
93
+ };
94
+ /**
95
+ * Hierarchical API surface exposed via `provide(INJECT_AGENT_APP, ...)`.
96
+ * Mirrors `BlokkliApp` for the editor — each member is a provider, and the
97
+ * orchestrator's flat state/actions sit at the top level.
98
+ */
99
+ export type AgentApp = {
100
+ socket: import('../providers/socketProvider').SocketProvider;
101
+ conversation: import('../providers/conversationProvider').ConversationProvider;
102
+ plan: import('../providers/planProvider').PlanProvider;
103
+ tools: import('../providers/toolsProvider').ToolsProvider;
104
+ } & import('../providers/agentProvider').AgentOrchestrator;
58
105
  /**
59
106
  * Makes specified adapter methods required (non-optional).
60
107
  */
@@ -1,4 +1,6 @@
1
- import { agentErrorTypeSchema } from "#blokkli/agent/shared/types";
1
+ import {
2
+ agentErrorTypeSchema
3
+ } from "#blokkli/agent/shared/types";
2
4
  import { z } from "zod";
3
5
  const conversationItemBase = z.object({
4
6
  id: z.string(),
@@ -197,6 +197,7 @@ export function pruneMessages(messages, keepRecentTurns, toolMetadata) {
197
197
  }
198
198
  continue;
199
199
  }
200
+ const hasToolResult = content.some((b) => b.type === "tool_result");
200
201
  for (let j = content.length - 1; j >= 0; j--) {
201
202
  const block = content[j];
202
203
  if (block.type === "tool_result") {
@@ -207,7 +208,7 @@ export function pruneMessages(messages, keepRecentTurns, toolMetadata) {
207
208
  } else {
208
209
  block.content = compressToolResult(block.content);
209
210
  }
210
- } else if (block.type === "text" || block.type === "skill") {
211
+ } else if (hasToolResult && (block.type === "text" || block.type === "skill")) {
211
212
  content.splice(j, 1);
212
213
  }
213
214
  }
@@ -1,4 +1,4 @@
1
- import { B as BlokkliModule } from '../../shared/editor.BTOBvmaz.mjs';
1
+ import { B as BlokkliModule } from '../../shared/editor.Bpw1EP57.mjs';
2
2
  import 'nuxt/schema';
3
3
  import 'consola';
4
4
  import '../../../dist/global/types/definitions.js';
@@ -1,4 +1,4 @@
1
- import { B as BlokkliModule } from '../../shared/editor.BTOBvmaz.mjs';
1
+ import { B as BlokkliModule } from '../../shared/editor.Bpw1EP57.mjs';
2
2
  import 'nuxt/schema';
3
3
  import 'consola';
4
4
  import '../../../dist/global/types/definitions.js';
@@ -14,7 +14,7 @@ declare const _default: (options?: {
14
14
  * template entity.
15
15
  */
16
16
  templateEditRouteName?: string;
17
- }) => BlokkliModule<{
17
+ } | undefined) => BlokkliModule<{
18
18
  /**
19
19
  * The name of the route that is used for editing template entities.
20
20
  *
@@ -1,4 +1,4 @@
1
- import { B as BlokkliModule } from '../../shared/editor.BTOBvmaz.mjs';
1
+ import { B as BlokkliModule } from '../../shared/editor.Bpw1EP57.mjs';
2
2
  import 'nuxt/schema';
3
3
  import 'consola';
4
4
  import '../../../dist/global/types/definitions.js';
@@ -1,4 +1,4 @@
1
- export { b as Blokkli, B as BlokkliModule, d as defineBlokkliModule } from '../shared/editor.BTOBvmaz.mjs';
1
+ export { b as Blokkli, B as BlokkliModule, d as defineBlokkliModule } from '../shared/editor.Bpw1EP57.mjs';
2
2
  import 'nuxt/schema';
3
3
  import 'consola';
4
4
  import '../../dist/global/types/definitions.js';
@@ -1,4 +1,4 @@
1
- import { B as BlokkliModule } from '../../shared/editor.BTOBvmaz.mjs';
1
+ import { B as BlokkliModule } from '../../shared/editor.Bpw1EP57.mjs';
2
2
  import 'nuxt/schema';
3
3
  import 'consola';
4
4
  import '../../../dist/global/types/definitions.js';
@@ -6,6 +6,6 @@ import '../../../dist/global/types/theme.js';
6
6
  import '@nuxt/kit';
7
7
  import '../../../dist/global/types/features.js';
8
8
 
9
- declare const _default: (options?: object) => BlokkliModule<object>;
9
+ declare const _default: (options?: object | undefined) => BlokkliModule<object>;
10
10
 
11
11
  export { _default as default };
@@ -1,4 +1,4 @@
1
- import { B as BlokkliModule } from '../../shared/editor.BTOBvmaz.mjs';
1
+ import { B as BlokkliModule } from '../../shared/editor.Bpw1EP57.mjs';
2
2
  import 'nuxt/schema';
3
3
  import 'consola';
4
4
  import '../../../dist/global/types/definitions.js';
@@ -6,6 +6,6 @@ import '../../../dist/global/types/theme.js';
6
6
  import '@nuxt/kit';
7
7
  import '../../../dist/global/types/features.js';
8
8
 
9
- declare const _default: (options?: object) => BlokkliModule<object>;
9
+ declare const _default: (options?: object | undefined) => BlokkliModule<object>;
10
10
 
11
11
  export { _default as default };