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

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 (113) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +2 -1
  3. package/dist/modules/agent/index.mjs +75 -35
  4. package/dist/modules/agent/runtime/app/composables/agentProvider.d.ts +1 -0
  5. package/dist/modules/agent/runtime/app/composables/agentProvider.js +51 -7
  6. package/dist/modules/agent/runtime/app/features/agent/Panel/Attachment/PreviewCode/index.d.vue.ts +6 -0
  7. package/dist/modules/agent/runtime/app/features/agent/Panel/Attachment/PreviewCode/index.vue +9 -0
  8. package/dist/modules/agent/runtime/app/features/agent/Panel/Attachment/PreviewCode/index.vue.d.ts +6 -0
  9. package/dist/modules/agent/runtime/app/features/agent/Panel/Attachment/PreviewCsv/index.d.vue.ts +6 -0
  10. package/dist/modules/agent/runtime/app/features/agent/Panel/Attachment/PreviewCsv/index.vue +31 -0
  11. package/dist/modules/agent/runtime/app/features/agent/Panel/Attachment/PreviewCsv/index.vue.d.ts +6 -0
  12. package/dist/modules/agent/runtime/app/features/agent/Panel/Attachment/PreviewHtml/index.d.vue.ts +6 -0
  13. package/dist/modules/agent/runtime/app/features/agent/Panel/Attachment/PreviewHtml/index.vue +12 -0
  14. package/dist/modules/agent/runtime/app/features/agent/Panel/Attachment/PreviewHtml/index.vue.d.ts +6 -0
  15. package/dist/modules/agent/runtime/app/features/agent/Panel/Attachment/PreviewMarkdown/index.d.vue.ts +6 -0
  16. package/dist/modules/agent/runtime/app/features/agent/Panel/Attachment/PreviewMarkdown/index.vue +17 -0
  17. package/dist/modules/agent/runtime/app/features/agent/Panel/Attachment/PreviewMarkdown/index.vue.d.ts +6 -0
  18. package/dist/modules/agent/runtime/app/features/agent/Panel/Attachment/index.vue +31 -1
  19. package/dist/modules/agent/runtime/app/features/agent/Panel/Conversation/Item/ServerTool/index.d.vue.ts +1 -1
  20. package/dist/modules/agent/runtime/app/features/agent/Panel/Conversation/Item/ServerTool/index.vue +9 -7
  21. package/dist/modules/agent/runtime/app/features/agent/Panel/Conversation/Item/ServerTool/index.vue.d.ts +1 -1
  22. package/dist/modules/agent/runtime/app/features/agent/Panel/Conversation/Item/Tool/index.d.vue.ts +3 -0
  23. package/dist/modules/agent/runtime/app/features/agent/Panel/Conversation/Item/Tool/index.vue +31 -7
  24. package/dist/modules/agent/runtime/app/features/agent/Panel/Conversation/Item/Tool/index.vue.d.ts +3 -0
  25. package/dist/modules/agent/runtime/app/features/agent/Panel/Conversation/Item/index.d.vue.ts +1 -0
  26. package/dist/modules/agent/runtime/app/features/agent/Panel/Conversation/Item/index.vue +18 -2
  27. package/dist/modules/agent/runtime/app/features/agent/Panel/Conversation/Item/index.vue.d.ts +1 -0
  28. package/dist/modules/agent/runtime/app/features/agent/Panel/Conversation/index.d.vue.ts +1 -0
  29. package/dist/modules/agent/runtime/app/features/agent/Panel/Conversation/index.vue +5 -2
  30. package/dist/modules/agent/runtime/app/features/agent/Panel/Conversation/index.vue.d.ts +1 -0
  31. package/dist/modules/agent/runtime/app/features/agent/Panel/DebugGallery/index.vue +2 -1
  32. package/dist/modules/agent/runtime/app/features/agent/Panel/DropHandler/index.d.vue.ts +17 -0
  33. package/dist/modules/agent/runtime/app/features/agent/Panel/DropHandler/index.vue +230 -0
  34. package/dist/modules/agent/runtime/app/features/agent/Panel/DropHandler/index.vue.d.ts +17 -0
  35. package/dist/modules/agent/runtime/app/features/agent/Panel/Input/index.d.vue.ts +4 -2
  36. package/dist/modules/agent/runtime/app/features/agent/Panel/Input/index.vue +5 -8
  37. package/dist/modules/agent/runtime/app/features/agent/Panel/Input/index.vue.d.ts +4 -2
  38. package/dist/modules/agent/runtime/app/features/agent/Panel/Plan/index.vue +1 -1
  39. package/dist/modules/agent/runtime/app/features/agent/Panel/index.d.vue.ts +1 -0
  40. package/dist/modules/agent/runtime/app/features/agent/Panel/index.vue +26 -3
  41. package/dist/modules/agent/runtime/app/features/agent/Panel/index.vue.d.ts +1 -0
  42. package/dist/modules/agent/runtime/app/features/agent/Transcript/index.vue +34 -1
  43. package/dist/modules/agent/runtime/app/features/agent/index.vue +2 -0
  44. package/dist/modules/agent/runtime/app/tools/ask_question/Component.vue +8 -2
  45. package/dist/modules/agent/runtime/app/tools/ask_question/index.d.ts +1 -0
  46. package/dist/modules/agent/runtime/app/tools/ask_question/index.js +9 -1
  47. package/dist/modules/agent/runtime/app/tools/check_readability/index.js +15 -16
  48. package/dist/modules/agent/runtime/app/tools/{analyze_content → get_readability_issues}/index.js +3 -2
  49. package/dist/modules/agent/runtime/app/tools/{batch_rewrite_text → update_text_fields}/Component.d.vue.ts +9 -0
  50. package/dist/modules/agent/runtime/app/tools/{batch_rewrite_text → update_text_fields}/Component.vue +80 -34
  51. package/dist/modules/agent/runtime/app/tools/{batch_rewrite_text → update_text_fields}/Component.vue.d.ts +9 -0
  52. package/dist/modules/agent/runtime/app/tools/update_text_fields/Details/index.d.vue.ts +6 -0
  53. package/dist/modules/agent/runtime/app/tools/update_text_fields/Details/index.vue +24 -0
  54. package/dist/modules/agent/runtime/app/tools/update_text_fields/Details/index.vue.d.ts +6 -0
  55. package/dist/modules/agent/runtime/app/tools/{batch_rewrite_text → update_text_fields}/Item.d.vue.ts +2 -0
  56. package/dist/modules/agent/runtime/app/tools/{batch_rewrite_text → update_text_fields}/Item.vue +9 -4
  57. package/dist/modules/agent/runtime/app/tools/{batch_rewrite_text → update_text_fields}/Item.vue.d.ts +2 -0
  58. package/dist/modules/agent/runtime/app/tools/update_text_fields/index.js +78 -0
  59. package/dist/modules/agent/runtime/app/types/index.d.ts +29 -2
  60. package/dist/modules/agent/runtime/app/types/index.js +3 -2
  61. package/dist/modules/agent/runtime/server/Session.d.ts +5 -1
  62. package/dist/modules/agent/runtime/server/Session.js +34 -6
  63. package/dist/modules/agent/runtime/server/default-skills/adding-new-paragraphs.js +1 -1
  64. package/dist/modules/agent/runtime/server/default-skills/fixReadability.js +3 -2
  65. package/dist/modules/agent/runtime/server/default-skills/pageReview.js +1 -1
  66. package/dist/modules/agent/runtime/server/default-skills/rewriteAndTranslate.js +2 -3
  67. package/dist/modules/agent/runtime/server/default-system-prompts/available-skills.js +1 -1
  68. package/dist/modules/agent/runtime/server/default-system-prompts/important-rules.js +1 -2
  69. package/dist/modules/agent/runtime/server/default-system-prompts/introduction.js +2 -1
  70. package/dist/modules/agent/runtime/server/default-system-prompts/page-context.js +1 -1
  71. package/dist/modules/agent/runtime/server/default-system-prompts/workflow.js +1 -1
  72. package/dist/modules/agent/runtime/server/helpers.js +2 -1
  73. package/dist/modules/agent/runtime/server/providers/anthropic.js +7 -4
  74. package/dist/modules/agent/runtime/server/providers/openai.js +167 -12
  75. package/dist/modules/agent/runtime/server/providers/types.d.ts +7 -2
  76. package/dist/modules/agent/runtime/server/server-tools/complete_plan_step/index.js +15 -0
  77. package/dist/modules/agent/runtime/server/server-tools/index.d.ts +6 -0
  78. package/dist/modules/agent/runtime/server/server-tools/{load_skill → load_skills}/index.d.ts +2 -2
  79. package/dist/modules/agent/runtime/server/server-tools/load_skills/index.js +80 -0
  80. package/dist/modules/agent/runtime/server/server-tools/load_tools/index.js +1 -0
  81. package/dist/modules/agent/runtime/server/skills/types.d.ts +4 -0
  82. package/dist/modules/agent/runtime/shared/types.d.ts +20 -2
  83. package/dist/modules/agent/runtime/shared/types.js +6 -0
  84. package/dist/modules/charts/runtime/blokkli/skills/charts.js +12 -3
  85. package/dist/runtime/editor/components/DiffViewer/DiffDisplay/index.d.vue.ts +9 -0
  86. package/dist/runtime/editor/components/DiffViewer/DiffDisplay/index.vue +31 -0
  87. package/dist/runtime/editor/components/DiffViewer/DiffDisplay/index.vue.d.ts +9 -0
  88. package/dist/runtime/editor/components/DiffViewer/DiffValue.vue +7 -4
  89. package/dist/runtime/editor/components/DiffViewer/State.vue +8 -30
  90. package/dist/runtime/editor/components/FlexTextarea/index.d.vue.ts +2 -1
  91. package/dist/runtime/editor/components/FlexTextarea/index.vue +1 -1
  92. package/dist/runtime/editor/components/FlexTextarea/index.vue.d.ts +2 -1
  93. package/dist/runtime/editor/components/index.d.ts +2 -1
  94. package/dist/runtime/editor/components/index.js +2 -0
  95. package/dist/runtime/editor/css/output.css +1 -1
  96. package/dist/runtime/editor/features/analyze/index.vue +1 -1
  97. package/dist/runtime/editor/features/edit/index.vue +20 -0
  98. package/dist/runtime/editor/plugins/Sidebar/Detached/index.d.vue.ts +1 -1
  99. package/dist/runtime/editor/plugins/Sidebar/Detached/index.vue.d.ts +1 -1
  100. package/dist/runtime/editor/plugins/Sidebar/index.d.vue.ts +1 -1
  101. package/dist/runtime/editor/plugins/Sidebar/index.vue.d.ts +1 -1
  102. package/dist/runtime/editor/providers/definition.d.ts +2 -1
  103. package/dist/runtime/editor/providers/definition.js +5 -1
  104. package/dist/runtime/editor/providers/storage.js +1 -1
  105. package/dist/runtime/editor/translations/de.json +4 -0
  106. package/dist/runtime/editor/translations/fr.json +4 -0
  107. package/dist/runtime/editor/translations/gsw_CH.json +4 -0
  108. package/dist/runtime/editor/translations/it.json +4 -0
  109. package/package.json +3 -2
  110. package/dist/modules/agent/runtime/app/tools/batch_rewrite_text/index.js +0 -55
  111. package/dist/modules/agent/runtime/server/server-tools/load_skill/index.js +0 -58
  112. /package/dist/modules/agent/runtime/app/tools/{analyze_content → get_readability_issues}/index.d.ts +0 -0
  113. /package/dist/modules/agent/runtime/app/tools/{batch_rewrite_text → update_text_fields}/index.d.ts +0 -0
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@blokkli/editor",
3
3
  "configKey": "blokkli",
4
- "version": "2.0.0-alpha.37",
4
+ "version": "2.0.0-alpha.39",
5
5
  "compatibility": {
6
6
  "nuxt": ">=3.15.0"
7
7
  },
package/dist/module.mjs CHANGED
@@ -18,7 +18,7 @@ import { d as defineCodeTemplate, a as defineFileTemplate, w as withHelper } fro
18
18
  import { defu, createDefu } from 'defu';
19
19
 
20
20
  const name = "@blokkli/editor";
21
- const version = "2.0.0-alpha.37";
21
+ const version = "2.0.0-alpha.39";
22
22
 
23
23
  function sortObjectKeys(obj) {
24
24
  if (Array.isArray(obj)) {
@@ -1555,6 +1555,7 @@ const USED_MATERIAL_ICONS = [
1555
1555
  "bk_mdi_info-fill",
1556
1556
  "bk_mdi_ink_selection",
1557
1557
  "bk_mdi_inventory",
1558
+ "bk_mdi_keyboard_arrow_down",
1558
1559
  "bk_mdi_keyboard_command_key",
1559
1560
  "bk_mdi_lists",
1560
1561
  "bk_mdi_logo_dev",
@@ -8,7 +8,7 @@ import { d as defineCodeTemplate } from '../../shared/editor.6D5vApr0.mjs';
8
8
  import MagicString from 'magic-string';
9
9
  import { parse } from 'acorn';
10
10
  import { walk } from 'estree-walker-ts';
11
- import { transformSync } from 'esbuild';
11
+ import { transformSync, buildSync } from 'esbuild';
12
12
 
13
13
  function toImportName(prefix, fileName) {
14
14
  const name = fileName.split(/[-_]/).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
@@ -253,27 +253,18 @@ export const toolDefinitions: ServerToolMetadata[]
253
253
  }
254
254
 
255
255
  const QUERY = "?blokkliAgentTool";
256
- const PROPERTIES_TO_REMOVE = /* @__PURE__ */ new Set([
257
- "execute",
258
- "resultSchema",
259
- "component",
260
- "label",
261
- "prunedSummary",
262
- "mockParams",
263
- "mockParamsVariants",
264
- "requiresApproval",
265
- "icon"
266
- ]);
267
- const SERVER_SAFE_IMPORTS = /* @__PURE__ */ new Set([
268
- "zod",
269
- "../schemas",
270
- "#blokkli/agent/app/tools/schemas",
271
- "../chart_schemas",
272
- "#blokkli-build/charts-config"
256
+ const PROPERTIES_TO_KEEP = /* @__PURE__ */ new Set([
257
+ "name",
258
+ "description",
259
+ "category",
260
+ "paramsSchema",
261
+ "modes",
262
+ "lazy",
263
+ "volatile",
264
+ "requiredAdapterMethods",
265
+ "requiredFeatures",
266
+ "resolve"
273
267
  ]);
274
- function isServerSafeImport(source) {
275
- return SERVER_SAFE_IMPORTS.has(source);
276
- }
277
268
  function agentToolStripPlugin() {
278
269
  return {
279
270
  name: "blokkli:agent-tool-strip",
@@ -299,7 +290,7 @@ function agentToolStripPlugin() {
299
290
  try {
300
291
  rawSource = fs.readFileSync(filePath, "utf-8");
301
292
  } catch {
302
- this.error(`Cannot read agent tool file: ${filePath}`);
293
+ return this.error(`Cannot read agent tool file: ${filePath}`);
303
294
  }
304
295
  const { code: jsSource } = transformSync(rawSource, {
305
296
  loader: "ts",
@@ -395,25 +386,61 @@ function validateTransformedOutput(output, filePath) {
395
386
  }
396
387
  return null;
397
388
  }
398
- function transformToolSource(source, filePath) {
399
- const ast = parse(source, {
389
+ function treeShake(code) {
390
+ const result = buildSync({
391
+ stdin: { contents: code, loader: "js", resolveDir: "/tmp" },
392
+ bundle: true,
393
+ write: false,
394
+ format: "esm",
395
+ target: "esnext",
396
+ treeShaking: true,
397
+ external: ["*"]
398
+ });
399
+ return result.outputFiles[0].text;
400
+ }
401
+ function removeDeadImports(code) {
402
+ const ast = parse(code, {
400
403
  sourceType: "module",
401
404
  ecmaVersion: "latest"
402
405
  });
403
- const exportInfo = findToolExport(ast);
404
- if (!exportInfo) {
405
- return source;
406
- }
407
- const s = new MagicString(source);
408
- const { toolObject, call } = exportInfo;
406
+ const importRanges = [];
407
+ walk(ast, {
408
+ enter(node) {
409
+ if (node.type === "ImportDeclaration") {
410
+ const n = node;
411
+ importRanges.push({ start: n.start, end: n.end });
412
+ }
413
+ },
414
+ leave() {
415
+ }
416
+ });
417
+ const usedIds = /* @__PURE__ */ new Set();
418
+ walk(ast, {
419
+ enter(node) {
420
+ if (node.type === "Identifier") {
421
+ const n = node;
422
+ const inImport = importRanges.some(
423
+ (r) => n.start >= r.start && n.start < r.end
424
+ );
425
+ if (!inImport) {
426
+ usedIds.add(n.name);
427
+ }
428
+ }
429
+ },
430
+ leave() {
431
+ }
432
+ });
433
+ const s = new MagicString(code);
409
434
  walk(ast, {
410
435
  enter(node) {
411
436
  if (node.type !== "ImportDeclaration") return;
412
437
  const importDecl = node;
413
- const importSource = importDecl.source.value;
414
- if (!isServerSafeImport(importSource)) {
438
+ const hasUsedBinding = (importDecl.specifiers || []).some(
439
+ (spec) => usedIds.has(spec.local.name)
440
+ );
441
+ if (!hasUsedBinding) {
415
442
  let removeEnd = importDecl.end;
416
- if (source[removeEnd] === "\n") {
443
+ if (code[removeEnd] === "\n") {
417
444
  removeEnd++;
418
445
  }
419
446
  s.remove(importDecl.start, removeEnd);
@@ -422,6 +449,19 @@ function transformToolSource(source, filePath) {
422
449
  leave() {
423
450
  }
424
451
  });
452
+ return s.toString();
453
+ }
454
+ function transformToolSource(source, filePath) {
455
+ const ast = parse(source, {
456
+ sourceType: "module",
457
+ ecmaVersion: "latest"
458
+ });
459
+ const exportInfo = findToolExport(ast);
460
+ if (!exportInfo) {
461
+ return source;
462
+ }
463
+ const s = new MagicString(source);
464
+ const { toolObject, call } = exportInfo;
425
465
  for (const prop of toolObject.properties) {
426
466
  if (prop.type !== "Property") continue;
427
467
  const key = prop.key;
@@ -431,7 +471,7 @@ function transformToolSource(source, filePath) {
431
471
  } else if (key.type === "Literal" && typeof key.value === "string") {
432
472
  name = key.value;
433
473
  }
434
- if (name && PROPERTIES_TO_REMOVE.has(name)) {
474
+ if (name && !PROPERTIES_TO_KEEP.has(name)) {
435
475
  const propNode = prop;
436
476
  let removeEnd = propNode.end;
437
477
  const afterProp = source.substring(removeEnd);
@@ -444,7 +484,7 @@ function transformToolSource(source, filePath) {
444
484
  }
445
485
  s.overwrite(call.start, toolObject.start, "");
446
486
  s.overwrite(toolObject.end, call.end, "");
447
- const result = s.toString();
487
+ const result = removeDeadImports(treeShake(s.toString()));
448
488
  const error = validateTransformedOutput(result, filePath);
449
489
  if (error) {
450
490
  throw new Error(error);
@@ -43,6 +43,7 @@ export type AgentProvider = {
43
43
  newConversation: () => void;
44
44
  getTranscript: () => void;
45
45
  onToolComponentDone: (result: unknown) => void;
46
+ toolDetails: Map<string, unknown>;
46
47
  transcriptContent: Ref<Transcript | null>;
47
48
  showTranscript: Ref<boolean>;
48
49
  conversationList: Ref<AgentConversationSummary[]>;
@@ -1,4 +1,4 @@
1
- import { ref, readonly, watch } from "#imports";
1
+ import { ref, readonly, reactive, watch } from "#imports";
2
2
  import {
3
3
  conversationItemSchema
4
4
  } from "#blokkli/agent/app/types";
@@ -21,7 +21,8 @@ export default function(app, adapter, agentName) {
21
21
  let ws = null;
22
22
  let reconnectTimeout = null;
23
23
  let pingInterval = null;
24
- let hasEverConnected = false;
24
+ let reconnectAttempts = 0;
25
+ const MAX_RECONNECT_ATTEMPTS = 10;
25
26
  const isConnected = ref(false);
26
27
  const isReady = ref(false);
27
28
  const hasBeenReady = ref(false);
@@ -43,6 +44,7 @@ export default function(app, adapter, agentName) {
43
44
  const activeConversationId = ref(null);
44
45
  const conversationList = ref([]);
45
46
  const showConversationList = ref(false);
47
+ const toolDetails = reactive(/* @__PURE__ */ new Map());
46
48
  async function saveCurrentConversation(serverState) {
47
49
  if (!adapter.agentConversations) return;
48
50
  if (!conversation.value.length) return;
@@ -177,15 +179,30 @@ export default function(app, adapter, agentName) {
177
179
  }
178
180
  function onWebSocketOpen() {
179
181
  isConnected.value = true;
182
+ reconnectAttempts = 0;
180
183
  pingInterval = window.setInterval(() => {
181
184
  send({ type: "ping" });
182
185
  }, 3e4);
183
186
  onConnect();
184
187
  }
185
188
  function onWebSocketClose() {
189
+ if (pingInterval) {
190
+ window.clearInterval(pingInterval);
191
+ pingInterval = null;
192
+ }
186
193
  isConnected.value = false;
187
194
  isReady.value = false;
188
195
  isProcessing.value = false;
196
+ reconnectAttempts++;
197
+ if (reconnectAttempts > MAX_RECONNECT_ATTEMPTS) {
198
+ conversation.value.push({
199
+ type: "error",
200
+ id: generateId(),
201
+ errorType: "connection",
202
+ timestamp: Date.now()
203
+ });
204
+ return;
205
+ }
189
206
  reconnectTimeout = window.setTimeout(() => {
190
207
  if (!isConnected.value) {
191
208
  connect();
@@ -204,8 +221,16 @@ export default function(app, adapter, agentName) {
204
221
  }
205
222
  }
206
223
  function connect() {
207
- if (hasEverConnected) return;
208
- hasEverConnected = true;
224
+ if (ws && (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING)) {
225
+ return;
226
+ }
227
+ if (ws) {
228
+ ws.removeEventListener("open", onWebSocketOpen);
229
+ ws.removeEventListener("close", onWebSocketClose);
230
+ ws.removeEventListener("error", onWebSocketError);
231
+ ws.removeEventListener("message", onWebSocketMessage);
232
+ ws = null;
233
+ }
209
234
  const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
210
235
  const url = `${protocol}//${window.location.host}/api/blokkli/agent`;
211
236
  ws = new WebSocket(url);
@@ -584,13 +609,29 @@ export default function(app, adapter, agentName) {
584
609
  timestamp
585
610
  });
586
611
  activeItem.value = null;
612
+ if (toolDef.buildDetails) {
613
+ try {
614
+ const detailsSource = typeof result === "object" && result !== null && "_details" in result ? result._details : result;
615
+ const details = toolDef.buildDetails(detailsSource);
616
+ if (details != null) {
617
+ toolDetails.set(callId, details);
618
+ }
619
+ } catch {
620
+ }
621
+ }
587
622
  let resultForServer = result;
588
- if (toolDef.prunedSummary && typeof result === "object" && result !== null) {
623
+ if (typeof result === "object" && result !== null) {
624
+ if ("_details" in result) {
625
+ const { _details: _, ...rest } = result;
626
+ resultForServer = rest;
627
+ }
628
+ }
629
+ if (toolDef.prunedSummary && typeof resultForServer === "object" && resultForServer !== null) {
589
630
  try {
590
- const summary = toolDef.prunedSummary(result);
631
+ const summary = toolDef.prunedSummary(resultForServer);
591
632
  if (summary) {
592
633
  resultForServer = {
593
- ...result,
634
+ ...resultForServer,
594
635
  _summary: summary
595
636
  };
596
637
  }
@@ -834,6 +875,7 @@ export default function(app, adapter, agentName) {
834
875
  activeConversationId.value = null;
835
876
  plan.value = null;
836
877
  usageTurns.value = [];
878
+ toolDetails.clear();
837
879
  send({ type: "new_conversation" });
838
880
  }
839
881
  function getTranscript() {
@@ -878,6 +920,8 @@ export default function(app, adapter, agentName) {
878
920
  newConversation,
879
921
  getTranscript,
880
922
  onToolComponentDone,
923
+ // Tool details (ephemeral)
924
+ toolDetails,
881
925
  // Transcript dialog state
882
926
  transcriptContent,
883
927
  showTranscript,
@@ -0,0 +1,6 @@
1
+ type __VLS_Props = {
2
+ content: string;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;
@@ -0,0 +1,9 @@
1
+ <template>
2
+ <pre class="bk-agent-attachment-code"><code>{{ content }}</code></pre>
3
+ </template>
4
+
5
+ <script setup>
6
+ defineProps({
7
+ content: { type: String, required: true }
8
+ });
9
+ </script>
@@ -0,0 +1,6 @@
1
+ type __VLS_Props = {
2
+ content: string;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;
@@ -0,0 +1,6 @@
1
+ type __VLS_Props = {
2
+ content: string;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <table class="bk-agent-attachment-table">
3
+ <thead>
4
+ <tr>
5
+ <th v-for="(cell, j) in headerRow" :key="j">{{ cell }}</th>
6
+ </tr>
7
+ </thead>
8
+ <tbody>
9
+ <tr v-for="(row, i) in bodyRows" :key="i">
10
+ <td v-for="(cell, j) in row" :key="j">{{ cell }}</td>
11
+ </tr>
12
+ </tbody>
13
+ </table>
14
+ </template>
15
+
16
+ <script setup>
17
+ import { computed } from "#imports";
18
+ const props = defineProps({
19
+ content: { type: String, required: true }
20
+ });
21
+ function parseRow(line) {
22
+ return line.split(",").map((cell) => cell.trim());
23
+ }
24
+ const headerRow = computed(() => {
25
+ const firstLine = props.content.trim().split("\n")[0];
26
+ return firstLine ? parseRow(firstLine) : [];
27
+ });
28
+ const bodyRows = computed(() => {
29
+ return props.content.trim().split("\n").slice(1).map(parseRow);
30
+ });
31
+ </script>
@@ -0,0 +1,6 @@
1
+ type __VLS_Props = {
2
+ content: string;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;
@@ -0,0 +1,6 @@
1
+ type __VLS_Props = {
2
+ content: string;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;
@@ -0,0 +1,12 @@
1
+ <template>
2
+ <div
3
+ class="bk-agent-attachment-rendered bk-agent-message-text"
4
+ v-html="content"
5
+ />
6
+ </template>
7
+
8
+ <script setup>
9
+ defineProps({
10
+ content: { type: String, required: true }
11
+ });
12
+ </script>
@@ -0,0 +1,6 @@
1
+ type __VLS_Props = {
2
+ content: string;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;
@@ -0,0 +1,6 @@
1
+ type __VLS_Props = {
2
+ content: string;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;
@@ -0,0 +1,17 @@
1
+ <template>
2
+ <div
3
+ class="bk-agent-attachment-rendered bk-agent-message-text"
4
+ v-html="html"
5
+ />
6
+ </template>
7
+
8
+ <script setup>
9
+ import { computed } from "#imports";
10
+ import { marked } from "marked";
11
+ const props = defineProps({
12
+ content: { type: String, required: true }
13
+ });
14
+ const html = computed(() => {
15
+ return marked.parse(props.content, { gfm: true, breaks: true });
16
+ });
17
+ </script>
@@ -0,0 +1,6 @@
1
+ type __VLS_Props = {
2
+ content: string;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;
@@ -30,7 +30,7 @@
30
30
  class="bk-agent-attachment-modal"
31
31
  @cancel="showAttachment = false"
32
32
  >
33
- <div>{{ attachment.content }}</div>
33
+ <component :is="previewComponent" :content="bodyContent" />
34
34
  </DialogModal>
35
35
  </BlokkliTransition>
36
36
  </Teleport>
@@ -43,6 +43,17 @@ import {
43
43
  BlokkliTransition,
44
44
  DialogModal
45
45
  } from "#blokkli/editor/components";
46
+ import PreviewMarkdown from "./PreviewMarkdown/index.vue";
47
+ import PreviewHtml from "./PreviewHtml/index.vue";
48
+ import PreviewCode from "./PreviewCode/index.vue";
49
+ import PreviewCsv from "./PreviewCsv/index.vue";
50
+ const PREVIEW_COMPONENTS = {
51
+ markdown: PreviewMarkdown,
52
+ html: PreviewHtml,
53
+ code: PreviewCode,
54
+ csv: PreviewCsv,
55
+ plaintext: PreviewCode
56
+ };
46
57
  const props = defineProps({
47
58
  attachment: { type: Object, required: true },
48
59
  removable: { type: Boolean, required: false }
@@ -50,12 +61,31 @@ const props = defineProps({
50
61
  defineEmits(["remove"]);
51
62
  const { $t, ui } = useBlokkli();
52
63
  const showAttachment = ref(false);
64
+ const FILE_PREFIX = "--- File: ";
53
65
  const title = computed(() => {
54
66
  if (props.attachment.type === "text") {
67
+ const content = props.attachment.content;
68
+ if (content.startsWith(FILE_PREFIX)) {
69
+ const endIndex = content.indexOf(" ---\n");
70
+ if (endIndex !== -1) {
71
+ return content.slice(FILE_PREFIX.length, endIndex);
72
+ }
73
+ }
55
74
  return $t("aiAgentPastedText", "Pasted text");
56
75
  }
57
76
  return "";
58
77
  });
78
+ const bodyContent = computed(() => {
79
+ const content = props.attachment.content;
80
+ const headerEnd = content.indexOf(" ---\n");
81
+ if (content.startsWith(FILE_PREFIX) && headerEnd !== -1) {
82
+ return content.slice(headerEnd + 5);
83
+ }
84
+ return content;
85
+ });
86
+ const previewComponent = computed(() => {
87
+ return PREVIEW_COMPONENTS[props.attachment.format];
88
+ });
59
89
  const preview = computed(() => {
60
90
  return props.attachment.content.replace(/\s+/g, " ").trim().slice(0, 200);
61
91
  });
@@ -2,7 +2,7 @@ type __VLS_Props = {
2
2
  id: string;
3
3
  timestamp: number;
4
4
  type: 'server_tool';
5
- tool: 'load_skill' | 'load_tools' | 'create_plan' | 'complete_plan_step' | 'plan_completed';
5
+ tool: 'load_skills' | 'load_tools' | 'create_plan' | 'complete_plan_step' | 'plan_completed';
6
6
  label: string;
7
7
  };
8
8
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -1,11 +1,13 @@
1
1
  <template>
2
2
  <div class="bk-agent-assistant-bubble bk-is-tool bk-is-server-tool">
3
3
  <div class="bk-agent-tool-call bk-is-server-tool">
4
- <Icon
5
- :name="getServerSideToolIcon(tool)"
6
- class="bk-agent-tool-call-status"
7
- />
8
- <span>{{ serverToolLabel }}</span>
4
+ <div class="bk-agent-tool-call-inner">
5
+ <Icon
6
+ :name="getServerSideToolIcon(tool)"
7
+ class="bk-agent-tool-call-status"
8
+ />
9
+ <span>{{ serverToolLabel }}</span>
10
+ </div>
9
11
  </div>
10
12
  </div>
11
13
  </template>
@@ -22,7 +24,7 @@ const props = defineProps({
22
24
  });
23
25
  const { $t } = useBlokkli();
24
26
  const serverToolLabel = computed(() => {
25
- if (props.tool === "load_skill") {
27
+ if (props.tool === "load_skills") {
26
28
  return $t("aiAgentLoadSkill", 'Using skill "@label"').replace(
27
29
  "@label",
28
30
  props.label
@@ -55,7 +57,7 @@ const serverToolLabel = computed(() => {
55
57
  return props.label;
56
58
  });
57
59
  function getServerSideToolIcon(id) {
58
- if (id === "load_skill") {
60
+ if (id === "load_skills") {
59
61
  return "bk_mdi_book_2";
60
62
  }
61
63
  if (id === "create_plan") {
@@ -2,7 +2,7 @@ type __VLS_Props = {
2
2
  id: string;
3
3
  timestamp: number;
4
4
  type: 'server_tool';
5
- tool: 'load_skill' | 'load_tools' | 'create_plan' | 'complete_plan_step' | 'plan_completed';
5
+ tool: 'load_skills' | 'load_tools' | 'create_plan' | 'complete_plan_step' | 'plan_completed';
6
6
  label: string;
7
7
  };
8
8
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -1,3 +1,4 @@
1
+ import { type Component } from '#imports';
1
2
  type __VLS_Props = {
2
3
  id: string;
3
4
  timestamp: number;
@@ -7,6 +8,8 @@ type __VLS_Props = {
7
8
  label: string;
8
9
  status: 'active' | 'success' | 'error';
9
10
  isActive?: boolean;
11
+ details?: unknown;
12
+ detailsComponent?: Component;
10
13
  };
11
14
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
15
  declare const _default: typeof __VLS_export;
@@ -1,17 +1,38 @@
1
1
  <template>
2
2
  <div class="bk-agent-assistant-bubble bk-is-tool">
3
3
  <div class="bk-agent-tool-call" :class="toolStatusClass">
4
- <StatusIcon :status="toolStatus" />
5
- <span class="bk-agent-tool-call-name">{{
6
- label || formatToolName(tool)
7
- }}</span>
4
+ <div class="bk-agent-tool-call-inner">
5
+ <StatusIcon :status="toolStatus" />
6
+ <span class="bk-agent-tool-call-name">{{
7
+ label || formatToolName(tool)
8
+ }}</span>
9
+ <button
10
+ v-if="details != null && detailsComponent"
11
+ class="bk-agent-tool-details-toggle"
12
+ :class="{ 'bk-is-expanded': isExpanded }"
13
+ @click="isExpanded = !isExpanded"
14
+ >
15
+ <Icon name="bk_mdi_keyboard_arrow_down" />
16
+ </button>
17
+ </div>
18
+ <TransitionHeight
19
+ v-if="details != null && detailsComponent"
20
+ :duration="200"
21
+ opacity
22
+ >
23
+ <div v-if="isExpanded" class="bk-agent-tool-details">
24
+ <div class="bk-agent-tool-details-inner">
25
+ <component :is="detailsComponent" :details="details" />
26
+ </div>
27
+ </div>
28
+ </TransitionHeight>
8
29
  </div>
9
30
  </div>
10
31
  </template>
11
32
 
12
33
  <script setup>
13
- import { computed } from "#imports";
14
- import { StatusIcon } from "#blokkli/editor/components";
34
+ import { computed, ref } from "#imports";
35
+ import { StatusIcon, Icon, TransitionHeight } from "#blokkli/editor/components";
15
36
  const props = defineProps({
16
37
  id: { type: String, required: true },
17
38
  timestamp: { type: Number, required: true },
@@ -20,8 +41,11 @@ const props = defineProps({
20
41
  tool: { type: String, required: true },
21
42
  label: { type: String, required: true },
22
43
  status: { type: String, required: true },
23
- isActive: { type: Boolean, required: false }
44
+ isActive: { type: Boolean, required: false },
45
+ details: { type: null, required: false },
46
+ detailsComponent: { type: null, required: false }
24
47
  });
48
+ const isExpanded = ref(false);
25
49
  const toolStatus = computed(() => {
26
50
  if (props.isActive) return "active";
27
51
  return props.status;