All files / chat-messages si-tool-message.component.ts

96.42% Statements 27/28
100% Branches 9/9
100% Functions 7/7
96.15% Lines 25/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125                                          1x         35x           35x           35x           35x           35x           35x           35x                   35x 35x                     35x 35x       36x 35x 8x 8x             65x       66x 66x       84x     84x 5x       79x       18x 18x      
/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
import { Component, input, Signal, booleanAttribute } from '@angular/core';
import { SiCollapsiblePanelComponent } from '@siemens/element-ng/accordion';
import { SiIconComponent } from '@siemens/element-ng/icon';
import { TranslatableString, t } from '@siemens/element-translate-ng/translate';
 
import { SiChatMessageComponent } from './si-chat-message.component';
 
/** @experimental */
@Component({
  selector: 'si-tool-message',
  imports: [SiChatMessageComponent, SiIconComponent, SiCollapsiblePanelComponent],
  templateUrl: './si-tool-message.component.html',
  styleUrl: './si-tool-message.component.scss',
  host: {
    class: 'si-tool-message'
  }
})
export class SiToolMessageComponent {
  /**
   * The tool name/title
   * @defaultValue ''
   */
  readonly name = input<string>('');
 
  /**
   * Input arguments for the tool call (optional, JSON string or object)
   * @defaultValue undefined
   */
  readonly inputArguments = input<string | object>();
 
  /**
   * Output result from the tool call (optional, JSON string or object)
   * @defaultValue undefined
   */
  readonly output = input<string | object>();
 
  /**
   * Whether to expand the input arguments section by default
   * @defaultValue false
   */
  readonly expandInputArguments = input(false, { transform: booleanAttribute });
 
  /**
   * Whether to expand the output section by default
   * @defaultValue false
   */
  readonly expandOutput = input(false, { transform: booleanAttribute });
 
  /**
   * Whether the tool call is currently executing (shows skeleton)
   * @defaultValue false
   */
  readonly loading = input(false, { transform: booleanAttribute });
 
  /**
   * Custom tool icon name
   * @defaultValue 'element-maintenance'
   */
  readonly toolIcon = input('element-maintenance');
 
  /**
   * Label for the input arguments section
   *
   * @defaultValue
   * ```
   * t(() => $localize`:@@SI_TOOL_MESSAGE.INPUT_ARGUMENTS:Input Arguments`)
   * ```
   */
  readonly inputArgumentsLabel = input<TranslatableString>(
    t(() => $localize`:@@SI_TOOL_MESSAGE.INPUT_ARGUMENTS:Input Arguments`)
  );
 
  /**
   * Label for the output section
   *
   * @defaultValue
   * ```
   * t(() => $localize`:@@SI_TOOL_MESSAGE.OUTPUT:Output`)
   * ```
   */
  readonly outputLabel = input<TranslatableString>(
    t(() => $localize`:@@SI_TOOL_MESSAGE.OUTPUT:Output`)
  );
 
  protected formatData(data: string | object | Signal<string | object> | undefined): string {
    if (data === undefined || data === null) return '';
    if (typeof data === 'string') return data;
    try {
      return JSON.stringify(data, null, 2);
    } catch {
      return String(data);
    }
  }
 
  protected hasInputArguments(): boolean {
    return this.inputArguments() !== undefined && this.inputArguments() !== null;
  }
 
  protected hasOutput(): boolean {
    const outputValue = this.output();
    return outputValue !== undefined && outputValue !== null;
  }
 
  protected getLoadingState(): boolean {
    const loadingValue = this.loading();
 
    // If explicitly loading
    if (loadingValue) {
      return true;
    }
 
    // If output is empty string (not undefined), show loading
    return false;
  }
 
  protected getOutputValue(): string | object | undefined {
    const outputValue = this.output();
    return outputValue as string | object | undefined;
  }
}