@tylertech/forge-ai 0.11.2 → 0.11.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.
@@ -69,7 +69,8 @@ _AiAssistantResponseComponent_instances = /* @__PURE__ */ new WeakSet();
69
69
  hasVisibleContent_get = function() {
70
70
  return this.response.children.some((child) => {
71
71
  if (child.type === "text") {
72
- return child.content.trim().length > 0;
72
+ const content = typeof child.content === "string" ? child.content : "";
73
+ return content.trim().length > 0;
73
74
  }
74
75
  if (this.debugMode) {
75
76
  return true;
@@ -91,10 +92,11 @@ updateEmptyState_fn = function() {
91
92
  }
92
93
  };
93
94
  renderTextChunk_fn = function(child) {
94
- if (!child.content.trim()) {
95
+ const content = typeof child.content === "string" ? child.content : "";
96
+ if (!content.trim()) {
95
97
  return nothing;
96
98
  }
97
- const renderedHtml = __privateGet(this, _markdownController).getCachedHtml(child.messageId, child.content);
99
+ const renderedHtml = __privateGet(this, _markdownController).getCachedHtml(child.messageId, content);
98
100
  return html`<div class="text-chunk">${unsafeHTML(renderedHtml)}</div>`;
99
101
  };
100
102
  renderToolCall_fn = function(toolCall) {
@@ -211,9 +213,13 @@ toolbar_get = function() {
211
213
  if (this.response.status !== "complete") {
212
214
  return nothing;
213
215
  }
214
- const hasTextContent = this.response.children.some(
215
- (child) => child.type === "text" && child.content.trim().length > 0
216
- );
216
+ const hasTextContent = this.response.children.some((child) => {
217
+ if (child.type !== "text") {
218
+ return false;
219
+ }
220
+ const content = typeof child.content === "string" ? child.content : "";
221
+ return content.trim().length > 0;
222
+ });
217
223
  if (!hasTextContent) {
218
224
  return nothing;
219
225
  }
@@ -317,7 +317,8 @@ class AgUiAdapter extends AgentAdapter {
317
317
  #transformMessages(messages) {
318
318
  return messages.filter((msg) => msg.role === "user" || msg.role === "assistant" || msg.role === "system" || msg.role === "tool").filter((msg) => !msg.clientOnly).filter((msg) => {
319
319
  if (msg.role === "assistant") {
320
- return msg.content.trim().length > 0 || msg.toolCalls && msg.toolCalls.length > 0;
320
+ const content = typeof msg.content === "string" ? msg.content : "";
321
+ return content.trim().length > 0 || msg.toolCalls && msg.toolCalls.length > 0;
321
322
  }
322
323
  return true;
323
324
  }).map((msg) => {
@@ -21,10 +21,11 @@ class MarkdownStreamController {
21
21
  return `${messageId}:${hash}`;
22
22
  }
23
23
  getCachedHtml(messageId, content) {
24
- const key = this.#getCacheKey(messageId, content);
24
+ const str = String(content ?? "");
25
+ const key = this.#getCacheKey(messageId, str);
25
26
  let html = this.#markdownCache.get(key);
26
27
  if (!html) {
27
- html = renderMarkdown(content);
28
+ html = renderMarkdown(str);
28
29
  this.#markdownCache.set(key, html);
29
30
  if (this.#markdownCache.size > 100) {
30
31
  const firstKey = this.#markdownCache.keys().next().value;
@@ -210,7 +210,13 @@ thinkingIndicator_get = function() {
210
210
  const lastItem = this.messageItems[this.messageItems.length - 1];
211
211
  if (lastItem?.type === "assistant") {
212
212
  const response = lastItem.data;
213
- const hasTextContent = response.children.some((c) => c.type === "text" && c.content.trim().length > 0);
213
+ const hasTextContent = response.children.some((c) => {
214
+ if (c.type !== "text") {
215
+ return false;
216
+ }
217
+ const content = typeof c.content === "string" ? c.content : "";
218
+ return content.trim().length > 0;
219
+ });
214
220
  if (hasTextContent) {
215
221
  return nothing;
216
222
  }
@@ -261,13 +267,14 @@ messages_get = function() {
261
267
  return __privateMethod(this, _AiMessageThreadComponent_instances, renderToolCall_fn).call(this, item.data);
262
268
  }
263
269
  const msg = item.data;
270
+ const content = typeof msg.content === "string" ? msg.content : "";
264
271
  if (msg.role === "user") {
265
- const renderedHtml = __privateGet(this, _markdownController).getCachedHtml(msg.id, msg.content);
272
+ const renderedHtml = __privateGet(this, _markdownController).getCachedHtml(msg.id, content);
266
273
  return html`
267
274
  <forge-ai-user-message
268
275
  message-id=${msg.id}
269
276
  .timestamp=${msg.timestamp}
270
- .content=${msg.content}
277
+ .content=${content}
271
278
  ?streaming=${this.showThinking}
272
279
  @forge-ai-user-message-copy=${(e) => __privateMethod(this, _AiMessageThreadComponent_instances, handleUserCopy_fn).call(this, e.detail.messageId)}
273
280
  @forge-ai-user-message-resend=${(e) => __privateMethod(this, _AiMessageThreadComponent_instances, handleUserResend_fn).call(this, e.detail.messageId)}
@@ -276,9 +283,9 @@ messages_get = function() {
276
283
  </forge-ai-user-message>
277
284
  `;
278
285
  } else if (msg.role === "system") {
279
- return html`<div class="system-message">${msg.content}</div>`;
286
+ return html`<div class="system-message">${content}</div>`;
280
287
  } else if (msg.status === "error") {
281
- const renderedHtml = __privateGet(this, _markdownController).getCachedHtml(msg.id, msg.content);
288
+ const renderedHtml = __privateGet(this, _markdownController).getCachedHtml(msg.id, content);
282
289
  return html`
283
290
  <forge-ai-error-message>
284
291
  <span slot="title">Error</span>
@@ -286,8 +293,8 @@ messages_get = function() {
286
293
  </forge-ai-error-message>
287
294
  `;
288
295
  } else {
289
- return when(msg.content?.trim().length, () => {
290
- const renderedHtml = __privateGet(this, _markdownController).getCachedHtml(msg.id, msg.content);
296
+ return when(content.trim().length, () => {
297
+ const renderedHtml = __privateGet(this, _markdownController).getCachedHtml(msg.id, content);
291
298
  return html`<forge-ai-response-message>${unsafeHTML(renderedHtml)}</forge-ai-response-message>`;
292
299
  });
293
300
  }
@@ -266,7 +266,8 @@ class ChatbotCoreController {
266
266
  this.#adapter.sendToolResult(toolCallId, result, this.getMessages());
267
267
  }
268
268
  async sendMessage(config) {
269
- if (!config.content.trim() || !this.#adapter || this.isStreaming) {
269
+ const content = typeof config.content === "string" ? config.content : "";
270
+ if (!content.trim() || !this.#adapter || this.isStreaming) {
270
271
  if (!this.#adapter) {
271
272
  console.warn("No adapter configured.");
272
273
  }
@@ -278,7 +279,7 @@ class ChatbotCoreController {
278
279
  const userMessage = {
279
280
  id: generateId(),
280
281
  role: "user",
281
- content: config.content,
282
+ content,
282
283
  timestamp: config.timestamp ?? Date.now(),
283
284
  status: "pending"
284
285
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tylertech/forge-ai",
3
- "version": "0.11.2",
3
+ "version": "0.11.3",
4
4
  "description": "A library of Tyler Forge™ AI chat interface web components.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Tyler Technologies, Inc.",