dexto 1.1.2 → 1.1.3

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 (89) hide show
  1. package/README.md +270 -160
  2. package/agents/agent-registry.json +16 -2
  3. package/agents/agent-template.yml +6 -12
  4. package/agents/default-agent.yml +6 -16
  5. package/agents/nano-banana-agent/README.md +200 -0
  6. package/agents/nano-banana-agent/nano-banana-agent.yml +68 -0
  7. package/agents/podcast-agent/README.md +168 -0
  8. package/agents/podcast-agent/podcast-agent.yml +167 -0
  9. package/agents/triage-demo/billing-agent.yml +2 -2
  10. package/agents/triage-demo/product-info-agent.yml +2 -3
  11. package/agents/triage-demo/technical-support-agent.yml +2 -3
  12. package/dist/src/app/{chunk-OIBH674O.js → chunk-BKF5BGLX.js} +318 -35
  13. package/dist/src/app/{chunk-FVWAYUL4.js → chunk-N7FUUBGT.js} +1 -1
  14. package/dist/src/app/{chunk-UG5P4DIL.js → chunk-OONTQZRM.js} +2 -2
  15. package/dist/src/app/{cli-confirmation-handler-7BZ6BMSE.js → cli-confirmation-handler-7235V7GL.js} +1 -1
  16. package/dist/src/app/{errors-EYGUMLKB.js → errors-YCS63OK6.js} +1 -1
  17. package/dist/src/app/index.js +19 -8
  18. package/dist/src/app/{loader-LJJQ4NDP.js → loader-PVRMNHST.js} +2 -2
  19. package/dist/src/app/{path-O5L5AW7V.js → path-DJ5C7EUS.js} +1 -1
  20. package/dist/src/app/{registry-HIVAEL5E.js → registry-KOOLQYP4.js} +3 -3
  21. package/dist/src/app/{sqlite-backend-FK7U4D6Z.js → sqlite-backend-NCFS7FN6.js} +1 -1
  22. package/dist/src/app/webui/.next/standalone/.next/static/chunks/122-4d4c8aa883d114a2.js +1 -0
  23. package/dist/src/app/webui/.next/standalone/.next/static/chunks/216-f5dbf2145a48ae92.js +1 -0
  24. package/dist/src/app/webui/.next/standalone/.next/static/chunks/43-4f3d01c7feaf132f.js +1 -0
  25. package/dist/src/app/webui/.next/standalone/.next/static/chunks/app/{layout-43f98b6d34953fcf.js → layout-36c240720861a312.js} +1 -1
  26. package/dist/src/app/webui/.next/standalone/.next/static/chunks/app/page-ca08c66042cb54c8.js +1 -0
  27. package/dist/src/app/webui/.next/{static/chunks/app/playground/page-c51bb3cc58225dc3.js → standalone/.next/static/chunks/app/playground/page-07a79d22b26d37f4.js} +1 -1
  28. package/dist/src/app/webui/.next/standalone/.next/static/css/c1d26dc78adbeb53.css +3 -0
  29. package/dist/src/app/webui/.next/standalone/package.json +3 -1
  30. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/BUILD_ID +1 -1
  31. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/app-build-manifest.json +9 -9
  32. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/build-manifest.json +2 -2
  33. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/prerender-manifest.json +3 -3
  34. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/required-server-files.json +1 -1
  35. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  36. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/server/app/page.js +3 -4
  37. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/server/app/page.js.nft.json +1 -1
  38. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/server/app/page_client-reference-manifest.js +1 -1
  39. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/server/app/playground/page.js +2 -2
  40. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/server/app/playground/page.js.nft.json +1 -1
  41. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/server/app/playground/page_client-reference-manifest.js +1 -1
  42. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/server/chunks/213.js +1 -1
  43. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/server/chunks/489.js +1 -0
  44. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/server/pages/500.html +1 -1
  45. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/server/server-reference-manifest.json +1 -1
  46. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/static/chunks/122-4d4c8aa883d114a2.js +1 -0
  47. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/static/chunks/216-f5dbf2145a48ae92.js +1 -0
  48. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/static/chunks/43-4f3d01c7feaf132f.js +1 -0
  49. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/static/chunks/app/{layout-43f98b6d34953fcf.js → layout-36c240720861a312.js} +1 -1
  50. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/static/chunks/app/page-ca08c66042cb54c8.js +1 -0
  51. package/dist/src/app/webui/.next/standalone/{.next/static/chunks/app/playground/page-c51bb3cc58225dc3.js → src/app/webui/.next/static/chunks/app/playground/page-07a79d22b26d37f4.js} +1 -1
  52. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/static/css/c1d26dc78adbeb53.css +3 -0
  53. package/dist/src/app/webui/.next/standalone/src/app/webui/server.js +1 -1
  54. package/dist/src/app/webui/.next/static/chunks/122-4d4c8aa883d114a2.js +1 -0
  55. package/dist/src/app/webui/.next/static/chunks/216-f5dbf2145a48ae92.js +1 -0
  56. package/dist/src/app/webui/.next/static/chunks/43-4f3d01c7feaf132f.js +1 -0
  57. package/dist/src/app/webui/.next/static/chunks/app/{layout-43f98b6d34953fcf.js → layout-36c240720861a312.js} +1 -1
  58. package/dist/src/app/webui/.next/static/chunks/app/page-ca08c66042cb54c8.js +1 -0
  59. package/dist/src/app/webui/.next/{standalone/src/app/webui/.next/static/chunks/app/playground/page-c51bb3cc58225dc3.js → static/chunks/app/playground/page-07a79d22b26d37f4.js} +1 -1
  60. package/dist/src/app/webui/.next/static/css/c1d26dc78adbeb53.css +3 -0
  61. package/dist/src/core/{chunk-2O5JENNA.js → chunk-XABD32T2.js} +318 -35
  62. package/dist/src/core/index.cjs +320 -35
  63. package/dist/src/core/index.d.cts +3 -0
  64. package/dist/src/core/index.d.ts +3 -0
  65. package/dist/src/core/index.js +1 -1
  66. package/dist/src/core/{sqlite-backend-4KSJRUVL.js → sqlite-backend-3VNBKYIT.js} +1 -1
  67. package/package.json +3 -1
  68. package/dist/src/app/webui/.next/standalone/.next/static/chunks/262-807eb8fa558ce992.js +0 -1
  69. package/dist/src/app/webui/.next/standalone/.next/static/chunks/42-ae0665ff0534f075.js +0 -1
  70. package/dist/src/app/webui/.next/standalone/.next/static/chunks/500-99efaae6ea436094.js +0 -1
  71. package/dist/src/app/webui/.next/standalone/.next/static/chunks/app/page-77c27b87857033eb.js +0 -1
  72. package/dist/src/app/webui/.next/standalone/.next/static/css/3d91ad5ec330296f.css +0 -3
  73. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/server/chunks/950.js +0 -1
  74. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/static/chunks/262-807eb8fa558ce992.js +0 -1
  75. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/static/chunks/42-ae0665ff0534f075.js +0 -1
  76. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/static/chunks/500-99efaae6ea436094.js +0 -1
  77. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/static/chunks/app/page-77c27b87857033eb.js +0 -1
  78. package/dist/src/app/webui/.next/standalone/src/app/webui/.next/static/css/3d91ad5ec330296f.css +0 -3
  79. package/dist/src/app/webui/.next/static/chunks/262-807eb8fa558ce992.js +0 -1
  80. package/dist/src/app/webui/.next/static/chunks/42-ae0665ff0534f075.js +0 -1
  81. package/dist/src/app/webui/.next/static/chunks/500-99efaae6ea436094.js +0 -1
  82. package/dist/src/app/webui/.next/static/chunks/app/page-77c27b87857033eb.js +0 -1
  83. package/dist/src/app/webui/.next/static/css/3d91ad5ec330296f.css +0 -3
  84. /package/dist/src/app/webui/.next/standalone/.next/static/{sig2NLqxammCphOh8eQRQ → RkBbxCa0lrWNsf3yPd4rX}/_buildManifest.js +0 -0
  85. /package/dist/src/app/webui/.next/standalone/.next/static/{sig2NLqxammCphOh8eQRQ → RkBbxCa0lrWNsf3yPd4rX}/_ssgManifest.js +0 -0
  86. /package/dist/src/app/webui/.next/standalone/src/app/webui/.next/static/{sig2NLqxammCphOh8eQRQ → RkBbxCa0lrWNsf3yPd4rX}/_buildManifest.js +0 -0
  87. /package/dist/src/app/webui/.next/standalone/src/app/webui/.next/static/{sig2NLqxammCphOh8eQRQ → RkBbxCa0lrWNsf3yPd4rX}/_ssgManifest.js +0 -0
  88. /package/dist/src/app/webui/.next/static/{sig2NLqxammCphOh8eQRQ → RkBbxCa0lrWNsf3yPd4rX}/_buildManifest.js +0 -0
  89. /package/dist/src/app/webui/.next/static/{sig2NLqxammCphOh8eQRQ → RkBbxCa0lrWNsf3yPd4rX}/_ssgManifest.js +0 -0
@@ -2074,10 +2074,19 @@ ${source_default.white(JSON.stringify(args, null, 2))}`,
2074
2074
  borderColor = "red";
2075
2075
  title = "\u274C Tool Error";
2076
2076
  } else if (typeof result === "string") {
2077
- displayText = result;
2077
+ if (result.length > 1e3) {
2078
+ displayText = `${result.slice(0, 500)}... [${result.length - 500} chars omitted]`;
2079
+ } else {
2080
+ displayText = result;
2081
+ }
2078
2082
  } else {
2079
2083
  try {
2080
- displayText = JSON.stringify(result, null, 2);
2084
+ const resultStr = JSON.stringify(result, null, 2);
2085
+ if (resultStr.length > 2e3) {
2086
+ displayText = `${resultStr.slice(0, 1e3)}... [${resultStr.length - 1e3} chars omitted]`;
2087
+ } else {
2088
+ displayText = resultStr;
2089
+ }
2081
2090
  } catch {
2082
2091
  displayText = `[Unparseable result: ${typeof result}]`;
2083
2092
  }
@@ -2506,7 +2515,17 @@ var MCPClient = class {
2506
2515
  { timeout: this.timeout }
2507
2516
  // Use server-specific timeout, default 1 minute
2508
2517
  );
2509
- logger.debug(`Tool '${name}' result: ${JSON.stringify(result, null, 2)}`);
2518
+ const logResult = JSON.stringify(
2519
+ result,
2520
+ (key, value) => {
2521
+ if (key === "data" && typeof value === "string" && value.length > 100) {
2522
+ return `[Base64 data: ${value.length} chars]`;
2523
+ }
2524
+ return value;
2525
+ },
2526
+ 2
2527
+ );
2528
+ logger.debug(`Tool '${name}' result: ${logResult}`);
2510
2529
  if (result === null || result === void 0) {
2511
2530
  return "Tool executed successfully with no result data.";
2512
2531
  }
@@ -5885,6 +5904,8 @@ var ContextError = class {
5885
5904
 
5886
5905
  // src/core/context/utils.ts
5887
5906
  var DEFAULT_OVERHEAD_PER_MESSAGE = 4;
5907
+ var MIN_BASE64_HEURISTIC_LENGTH = 512;
5908
+ var MAX_TOOL_TEXT_CHARS = 8e3;
5888
5909
  function countMessagesTokens(history, tokenizer, overheadPerMessage = DEFAULT_OVERHEAD_PER_MESSAGE) {
5889
5910
  let total = 0;
5890
5911
  logger.debug(`Counting tokens for ${history.length} messages`);
@@ -5899,16 +5920,26 @@ function countMessagesTokens(history, tokenizer, overheadPerMessage = DEFAULT_OV
5899
5920
  total += tokenizer.countTokens(part.text);
5900
5921
  } else if (part.type === "image") {
5901
5922
  if (typeof part.image === "string") {
5902
- const byteLength = Math.floor(part.image.length * 3 / 4);
5903
- total += Math.ceil(byteLength / 1024);
5923
+ if (isDataUri(part.image)) {
5924
+ const base64Payload = extractBase64FromDataUri(part.image);
5925
+ const byteLength = base64LengthToBytes(base64Payload.length);
5926
+ total += Math.ceil(byteLength / 1024);
5927
+ } else {
5928
+ total += estimateTextTokens(part.image);
5929
+ }
5904
5930
  } else if (part.image instanceof Uint8Array || part.image instanceof Buffer || part.image instanceof ArrayBuffer) {
5905
5931
  const bytes = part.image instanceof ArrayBuffer ? part.image.byteLength : part.image.length;
5906
5932
  total += Math.ceil(bytes / 1024);
5907
5933
  }
5908
5934
  } else if (part.type === "file") {
5909
5935
  if (typeof part.data === "string") {
5910
- const byteLength = Math.floor(part.data.length * 3 / 4);
5911
- total += Math.ceil(byteLength / 1024);
5936
+ if (isDataUri(part.data)) {
5937
+ const base64Payload = extractBase64FromDataUri(part.data);
5938
+ const byteLength = base64LengthToBytes(base64Payload.length);
5939
+ total += Math.ceil(byteLength / 1024);
5940
+ } else {
5941
+ total += estimateTextTokens(part.data);
5942
+ }
5912
5943
  } else if (part.data instanceof Uint8Array || part.data instanceof Buffer || part.data instanceof ArrayBuffer) {
5913
5944
  const bytes = part.data instanceof ArrayBuffer ? part.data.byteLength : part.data.length;
5914
5945
  total += Math.ceil(bytes / 1024);
@@ -5950,7 +5981,7 @@ function getImageData(imagePart) {
5950
5981
  } else if (image instanceof URL) {
5951
5982
  return image.toString();
5952
5983
  }
5953
- console.warn("Unexpected image data type in getImageData:", typeof image);
5984
+ logger.warn(`Unexpected image data type in getImageData: ${typeof image}`);
5954
5985
  return "";
5955
5986
  }
5956
5987
  function getFileData(filePart) {
@@ -5966,7 +5997,7 @@ function getFileData(filePart) {
5966
5997
  } else if (data instanceof URL) {
5967
5998
  return data.toString();
5968
5999
  }
5969
- console.warn("Unexpected file data type in getFileData:", typeof data);
6000
+ logger.warn(`Unexpected file data type in getFileData: ${typeof data}`);
5970
6001
  return "";
5971
6002
  }
5972
6003
  function filterMessagesByLLMCapabilities(messages, config) {
@@ -6001,10 +6032,236 @@ function filterMessagesByLLMCapabilities(messages, config) {
6001
6032
  };
6002
6033
  });
6003
6034
  } catch (error) {
6004
- console.warn("Failed to filter messages by LLM capabilities:", error);
6035
+ logger.warn(`Failed to filter messages by LLM capabilities: ${String(error)}`);
6005
6036
  return messages;
6006
6037
  }
6007
6038
  }
6039
+ function isLikelyBase64String(value, minLength = MIN_BASE64_HEURISTIC_LENGTH) {
6040
+ if (!value || value.length < minLength) return false;
6041
+ if (value.startsWith("data:") && value.includes(";base64,")) return true;
6042
+ const b64Regex = /^[A-Za-z0-9+/=\r\n]+$/;
6043
+ if (!b64Regex.test(value)) return false;
6044
+ const nonWordRatio = (value.match(/[^A-Za-z0-9+/=]/g)?.length || 0) / value.length;
6045
+ return nonWordRatio < 0.01;
6046
+ }
6047
+ function parseDataUri(value) {
6048
+ if (!value.startsWith("data:")) return null;
6049
+ const commaIdx = value.indexOf(",");
6050
+ if (commaIdx === -1) return null;
6051
+ const meta = value.slice(5, commaIdx);
6052
+ if (!/;base64$/i.test(meta)) return null;
6053
+ const mediaType = meta.replace(/;base64$/i, "") || "application/octet-stream";
6054
+ const base64 = value.slice(commaIdx + 1);
6055
+ return { mediaType, base64 };
6056
+ }
6057
+ function sanitizeDeepObject(obj) {
6058
+ if (obj == null) return obj;
6059
+ if (typeof obj === "string") {
6060
+ if (isLikelyBase64String(obj)) {
6061
+ const approxBytes = Math.floor(obj.length * 3 / 4);
6062
+ logger.debug(
6063
+ `sanitizeDeepObject: replaced large base64 string (~${approxBytes} bytes) with placeholder`
6064
+ );
6065
+ return `[binary data omitted ~${approxBytes} bytes]`;
6066
+ }
6067
+ return obj;
6068
+ }
6069
+ if (Array.isArray(obj)) return obj.map((x) => sanitizeDeepObject(x));
6070
+ if (typeof obj === "object") {
6071
+ const out = {};
6072
+ for (const [k, v] of Object.entries(obj)) {
6073
+ out[k] = sanitizeDeepObject(v);
6074
+ }
6075
+ return out;
6076
+ }
6077
+ return obj;
6078
+ }
6079
+ function sanitizeToolResultToContent(result) {
6080
+ try {
6081
+ if (typeof result === "string") {
6082
+ const dataUri = parseDataUri(result);
6083
+ if (dataUri) {
6084
+ const mediaType = dataUri.mediaType;
6085
+ logger.debug(
6086
+ `sanitizeToolResultToContent: detected data URI (${mediaType}), converting to media part`
6087
+ );
6088
+ if (mediaType.startsWith("image/")) {
6089
+ return [{ type: "image", image: dataUri.base64, mimeType: mediaType }];
6090
+ }
6091
+ return [{ type: "file", data: dataUri.base64, mimeType: mediaType }];
6092
+ }
6093
+ if (isLikelyBase64String(result)) {
6094
+ logger.debug(
6095
+ "sanitizeToolResultToContent: detected base64-like string, converting to file part"
6096
+ );
6097
+ return [
6098
+ {
6099
+ type: "file",
6100
+ data: result,
6101
+ mimeType: "application/octet-stream",
6102
+ filename: "tool-output.bin"
6103
+ }
6104
+ ];
6105
+ }
6106
+ if (result.length > MAX_TOOL_TEXT_CHARS) {
6107
+ const head = result.slice(0, 4e3);
6108
+ const tail = result.slice(-1e3);
6109
+ logger.debug(
6110
+ `sanitizeToolResultToContent: truncating long text tool output (len=${result.length})`
6111
+ );
6112
+ return `${head}
6113
+ ... [${result.length - 5e3} chars omitted] ...
6114
+ ${tail}`;
6115
+ }
6116
+ return result;
6117
+ }
6118
+ if (Array.isArray(result)) {
6119
+ const parts = [];
6120
+ for (const item of result) {
6121
+ if (item == null) continue;
6122
+ if (typeof item === "string") {
6123
+ const dataUri = parseDataUri(item);
6124
+ if (dataUri) {
6125
+ const mt = dataUri.mediaType;
6126
+ if (mt.startsWith("image/"))
6127
+ parts.push({ type: "image", image: dataUri.base64, mimeType: mt });
6128
+ else parts.push({ type: "file", data: dataUri.base64, mimeType: mt });
6129
+ continue;
6130
+ }
6131
+ if (isLikelyBase64String(item)) {
6132
+ parts.push({
6133
+ type: "file",
6134
+ data: item,
6135
+ mimeType: "application/octet-stream",
6136
+ filename: "tool-output.bin"
6137
+ });
6138
+ continue;
6139
+ }
6140
+ parts.push({ type: "text", text: item });
6141
+ continue;
6142
+ }
6143
+ if (typeof item === "object") {
6144
+ const obj = item;
6145
+ if (obj.type === "text" && typeof obj.text === "string") {
6146
+ parts.push({ type: "text", text: obj.text });
6147
+ continue;
6148
+ }
6149
+ if (obj.type === "image" && obj.image !== void 0 || "image" in obj) {
6150
+ parts.push({
6151
+ type: "image",
6152
+ image: getImageData({ image: obj.image }),
6153
+ mimeType: obj.mimeType || "image/jpeg"
6154
+ });
6155
+ continue;
6156
+ }
6157
+ if (obj.type === "file" && obj.data !== void 0) {
6158
+ parts.push({
6159
+ type: "file",
6160
+ data: getFileData({ data: obj.data }),
6161
+ mimeType: obj.mimeType || "application/octet-stream",
6162
+ filename: obj.filename
6163
+ });
6164
+ continue;
6165
+ }
6166
+ if ("data" in obj && (typeof obj.mimeType === "string" || obj.filename)) {
6167
+ parts.push({
6168
+ type: "file",
6169
+ data: getFileData({ data: obj.data }),
6170
+ mimeType: obj.mimeType || "application/octet-stream",
6171
+ filename: obj.filename
6172
+ });
6173
+ continue;
6174
+ }
6175
+ const cleaned = sanitizeDeepObject(obj);
6176
+ parts.push({ type: "text", text: safeStringify(cleaned) });
6177
+ continue;
6178
+ }
6179
+ parts.push({ type: "text", text: String(item) });
6180
+ }
6181
+ return parts;
6182
+ }
6183
+ if (result && typeof result === "object") {
6184
+ const anyObj = result;
6185
+ if ("image" in anyObj) {
6186
+ return [
6187
+ {
6188
+ type: "image",
6189
+ image: getImageData({ image: anyObj.image }),
6190
+ mimeType: anyObj.mimeType || "image/jpeg"
6191
+ }
6192
+ ];
6193
+ }
6194
+ if ("data" in anyObj && anyObj.mimeType) {
6195
+ return [
6196
+ {
6197
+ type: "file",
6198
+ data: getFileData({ data: anyObj.data }),
6199
+ mimeType: anyObj.mimeType,
6200
+ filename: anyObj.filename
6201
+ }
6202
+ ];
6203
+ }
6204
+ const cleaned = sanitizeDeepObject(anyObj);
6205
+ return safeStringify(cleaned);
6206
+ }
6207
+ return safeStringify(result ?? "");
6208
+ } catch (err) {
6209
+ logger.warn(`sanitizeToolResultToContent failed, falling back to string: ${String(err)}`);
6210
+ try {
6211
+ return safeStringify(result ?? "");
6212
+ } catch {
6213
+ return String(result ?? "");
6214
+ }
6215
+ }
6216
+ }
6217
+ function summarizeToolContentForText(content) {
6218
+ if (!Array.isArray(content)) return String(content || "");
6219
+ const parts = [];
6220
+ for (const p of content) {
6221
+ if (p.type === "text") {
6222
+ parts.push(p.text);
6223
+ } else if (p.type === "image") {
6224
+ let bytes = 0;
6225
+ if (typeof p.image === "string") bytes = Math.floor(p.image.length * 3 / 4);
6226
+ else if (p.image instanceof ArrayBuffer) bytes = p.image.byteLength;
6227
+ else if (p.image instanceof Uint8Array) bytes = p.image.length;
6228
+ else if (p.image instanceof Buffer) bytes = p.image.length;
6229
+ parts.push(`[image ${p.mimeType || "image"} ~${Math.ceil(bytes / 1024)}KB]`);
6230
+ } else if (p.type === "file") {
6231
+ let bytes = 0;
6232
+ if (typeof p.data === "string") bytes = Math.floor(p.data.length * 3 / 4);
6233
+ else if (p.data instanceof ArrayBuffer) bytes = p.data.byteLength;
6234
+ else if (p.data instanceof Uint8Array) bytes = p.data.length;
6235
+ else if (p.data instanceof Buffer) bytes = p.data.length;
6236
+ const label = p.filename ? `${p.filename}` : `${p.mimeType || "file"}`;
6237
+ parts.push(`[file ${label} ~${Math.ceil(bytes / 1024)}KB]`);
6238
+ }
6239
+ }
6240
+ const summary = parts.join("\n");
6241
+ return summary.slice(0, 4e3);
6242
+ }
6243
+ function base64LengthToBytes(charLength) {
6244
+ return Math.floor(charLength * 3 / 4);
6245
+ }
6246
+ function isDataUri(str) {
6247
+ return str.startsWith("data:") && str.includes(";base64,");
6248
+ }
6249
+ function extractBase64FromDataUri(dataUri) {
6250
+ const commaIndex = dataUri.indexOf(",");
6251
+ return commaIndex !== -1 ? dataUri.substring(commaIndex + 1) : "";
6252
+ }
6253
+ function estimateTextTokens(text) {
6254
+ return Math.ceil(text.length / 4);
6255
+ }
6256
+ function toTextForToolMessage(content) {
6257
+ if (Array.isArray(content)) {
6258
+ return summarizeToolContentForText(content);
6259
+ }
6260
+ if (typeof content === "string") {
6261
+ return isLikelyBase64String(content) ? "[binary data omitted]" : content;
6262
+ }
6263
+ return String(content ?? "");
6264
+ }
6008
6265
 
6009
6266
  // src/core/context/compression/middle-removal.ts
6010
6267
  var MiddleRemovalStrategy = class {
@@ -6420,21 +6677,17 @@ ${prompt}`);
6420
6677
  throw ContextError.toolCallIdNameRequired();
6421
6678
  }
6422
6679
  let content;
6423
- if (result && typeof result === "object" && "image" in result) {
6424
- const imagePart = result;
6425
- content = [
6426
- {
6427
- type: "image",
6428
- image: getImageData(imagePart),
6429
- mimeType: imagePart.mimeType || "image/jpeg"
6430
- }
6431
- ];
6432
- } else if (typeof result === "string") {
6433
- content = result;
6434
- } else if (Array.isArray(result)) {
6435
- content = result;
6436
- } else {
6437
- content = JSON.stringify(result ?? "");
6680
+ content = sanitizeToolResultToContent(result);
6681
+ if (typeof content === "string") {
6682
+ const preview = content.slice(0, 200);
6683
+ logger.debug(
6684
+ `ContextManager: Storing tool result (text) for ${name} (len=${content.length}): ${preview}${content.length > 200 ? "..." : ""}`
6685
+ );
6686
+ } else if (Array.isArray(content)) {
6687
+ const summary = content.map(
6688
+ (p) => p.type === "text" ? `text(${p.text.length})` : p.type === "image" ? `image(${p.mimeType || "image"})` : `file(${p.mimeType || "file"})`
6689
+ ).join(", ");
6690
+ logger.debug(`ContextManager: Storing tool result (parts) for ${name}: [${summary}]`);
6438
6691
  }
6439
6692
  await this.addMessage({ role: "tool", content, toolCallId, name });
6440
6693
  }
@@ -7195,6 +7448,8 @@ var VercelLLMService = class {
7195
7448
  sessionEventBus;
7196
7449
  sessionId;
7197
7450
  toolSupportCache = /* @__PURE__ */ new Map();
7451
+ // Map of toolCallId -> queue of raw results to emit with that callId
7452
+ rawResultsByCallId = /* @__PURE__ */ new Map();
7198
7453
  /**
7199
7454
  * Helper to extract model ID from LanguageModel union type (string | LanguageModelV2)
7200
7455
  */
@@ -7233,13 +7488,20 @@ var VercelLLMService = class {
7233
7488
  if (tool) {
7234
7489
  acc[toolName] = {
7235
7490
  inputSchema: jsonSchema(tool.parameters),
7236
- execute: async (args) => {
7491
+ execute: async (args, options) => {
7237
7492
  try {
7238
- return await this.toolManager.executeTool(
7493
+ const rawResult = await this.toolManager.executeTool(
7239
7494
  toolName,
7240
7495
  args,
7241
7496
  this.sessionId
7242
7497
  );
7498
+ const callId = options.toolCallId;
7499
+ const queue = this.rawResultsByCallId.get(callId) ?? [];
7500
+ queue.push(rawResult);
7501
+ this.rawResultsByCallId.set(callId, queue);
7502
+ const safeContent = sanitizeToolResultToContent(rawResult);
7503
+ const summaryText = summarizeToolContentForText(safeContent);
7504
+ return summaryText;
7243
7505
  } catch (err) {
7244
7506
  if (err instanceof DextoRuntimeError && err.code === "tools_execution_denied" /* EXECUTION_DENIED */) {
7245
7507
  return { error: err.message, denied: true };
@@ -7393,10 +7655,19 @@ var VercelLLMService = class {
7393
7655
  }
7394
7656
  if (step.toolResults && step.toolResults.length > 0) {
7395
7657
  for (const toolResult of step.toolResults) {
7658
+ const callId = toolResult.toolCallId;
7659
+ const sanitized = toolResult.output;
7660
+ let raw;
7661
+ if (callId) {
7662
+ const q = this.rawResultsByCallId.get(callId) ?? [];
7663
+ raw = q.shift();
7664
+ if (q.length > 0) this.rawResultsByCallId.set(callId, q);
7665
+ else this.rawResultsByCallId.delete(callId);
7666
+ }
7396
7667
  this.sessionEventBus.emit("llmservice:toolResult", {
7397
7668
  toolName: toolResult.toolName,
7398
- result: toolResult.output,
7399
- callId: toolResult.toolCallId,
7669
+ result: raw ?? sanitized,
7670
+ callId,
7400
7671
  success: true
7401
7672
  });
7402
7673
  }
@@ -7561,10 +7832,19 @@ var VercelLLMService = class {
7561
7832
  }
7562
7833
  if (step.toolResults && step.toolResults.length > 0) {
7563
7834
  for (const toolResult of step.toolResults) {
7835
+ const callId = toolResult.toolCallId;
7836
+ const sanitized = toolResult.output;
7837
+ let raw;
7838
+ if (callId) {
7839
+ const q = this.rawResultsByCallId.get(callId) ?? [];
7840
+ raw = q.shift();
7841
+ if (q.length > 0) this.rawResultsByCallId.set(callId, q);
7842
+ else this.rawResultsByCallId.delete(callId);
7843
+ }
7564
7844
  this.sessionEventBus.emit("llmservice:toolResult", {
7565
7845
  toolName: toolResult.toolName,
7566
- result: toolResult.output,
7567
- callId: toolResult.toolCallId,
7846
+ result: raw ?? sanitized,
7847
+ callId,
7568
7848
  success: true
7569
7849
  });
7570
7850
  }
@@ -7705,7 +7985,7 @@ var OpenAIMessageFormatter = class {
7705
7985
  case "tool":
7706
7986
  formatted.push({
7707
7987
  role: "tool",
7708
- content: String(msg.content || ""),
7988
+ content: toTextForToolMessage(msg.content),
7709
7989
  tool_call_id: msg.toolCallId || ""
7710
7990
  });
7711
7991
  break;
@@ -8275,13 +8555,14 @@ var AnthropicMessageFormatter = class {
8275
8555
  formatted.push(pendingCall.assistantMsg);
8276
8556
  pendingCall.assistantMsg = null;
8277
8557
  }
8558
+ const safeContent = toTextForToolMessage(msg.content);
8278
8559
  const toolResultMsg = {
8279
8560
  role: "user",
8280
8561
  content: [
8281
8562
  {
8282
8563
  type: "tool_result",
8283
8564
  tool_use_id: msg.toolCallId,
8284
- content: String(msg.content || "")
8565
+ content: safeContent
8285
8566
  }
8286
8567
  ]
8287
8568
  };
@@ -8289,13 +8570,14 @@ var AnthropicMessageFormatter = class {
8289
8570
  pendingToolCalls.delete(msg.toolCallId);
8290
8571
  } else {
8291
8572
  logger.warn(`Tool result found without matching tool call: ${msg.toolCallId}`);
8573
+ const orphanSafe = toTextForToolMessage(msg.content);
8292
8574
  const orphanToolResult = {
8293
8575
  role: "user",
8294
8576
  content: [
8295
8577
  {
8296
8578
  type: "tool_result",
8297
8579
  tool_use_id: msg.toolCallId,
8298
- content: String(msg.content || "")
8580
+ content: orphanSafe
8299
8581
  }
8300
8582
  ]
8301
8583
  };
@@ -10288,7 +10570,7 @@ var StorageManager = class {
10288
10570
  async createSQLiteBackend(config) {
10289
10571
  try {
10290
10572
  if (!SQLiteBackend) {
10291
- const module = await import("./sqlite-backend-4KSJRUVL.js");
10573
+ const module = await import("./sqlite-backend-3VNBKYIT.js");
10292
10574
  SQLiteBackend = module.SQLiteBackend;
10293
10575
  }
10294
10576
  logger.info(`Using SQLite database at ${config.path}`);
@@ -11518,6 +11800,7 @@ var AgentCardSchema = z10.object({
11518
11800
  }).strict();
11519
11801
  var AgentConfigSchema = z10.object({
11520
11802
  agentCard: AgentCardSchema.describe("Configuration for the agent card").optional(),
11803
+ greeting: z10.string().max(500).optional().describe("Default greeting text to show when a chat starts (for UI consumption)"),
11521
11804
  systemPrompt: SystemPromptConfigSchema.describe(
11522
11805
  "System prompt: string shorthand or structured config"
11523
11806
  ),