@c8y/ngx-components 1024.15.13 → 1024.16.5

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 (60) hide show
  1. package/fesm2022/c8y-ngx-components-ai-agent-chat.mjs +303 -63
  2. package/fesm2022/c8y-ngx-components-ai-agent-chat.mjs.map +1 -1
  3. package/fesm2022/c8y-ngx-components-ai-agents-html.mjs +9 -0
  4. package/fesm2022/c8y-ngx-components-ai-agents-html.mjs.map +1 -1
  5. package/fesm2022/c8y-ngx-components-ai-agents-scada.mjs +4 -0
  6. package/fesm2022/c8y-ngx-components-ai-agents-scada.mjs.map +1 -1
  7. package/fesm2022/c8y-ngx-components-ai-ai-chat.mjs +394 -52
  8. package/fesm2022/c8y-ngx-components-ai-ai-chat.mjs.map +1 -1
  9. package/fesm2022/c8y-ngx-components-ai.mjs +329 -19
  10. package/fesm2022/c8y-ngx-components-ai.mjs.map +1 -1
  11. package/fesm2022/c8y-ngx-components-context-dashboard.mjs +7 -1
  12. package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
  13. package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs +95 -76
  14. package/fesm2022/c8y-ngx-components-datapoint-explorer-view.mjs.map +1 -1
  15. package/fesm2022/c8y-ngx-components-datapoint-selector.mjs +92 -47
  16. package/fesm2022/c8y-ngx-components-datapoint-selector.mjs.map +1 -1
  17. package/fesm2022/c8y-ngx-components-echart.mjs +39 -12
  18. package/fesm2022/c8y-ngx-components-echart.mjs.map +1 -1
  19. package/fesm2022/c8y-ngx-components-time-context.mjs +13 -9
  20. package/fesm2022/c8y-ngx-components-time-context.mjs.map +1 -1
  21. package/fesm2022/c8y-ngx-components-widgets-definitions-html-widget-ai-config.mjs +3 -2
  22. package/fesm2022/c8y-ngx-components-widgets-definitions-html-widget-ai-config.mjs.map +1 -1
  23. package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.mjs +4 -6
  24. package/fesm2022/c8y-ngx-components-widgets-implementations-asset-table.mjs.map +1 -1
  25. package/fesm2022/c8y-ngx-components-widgets-implementations-scada.mjs +3 -2
  26. package/fesm2022/c8y-ngx-components-widgets-implementations-scada.mjs.map +1 -1
  27. package/fesm2022/c8y-ngx-components.mjs +65 -14
  28. package/fesm2022/c8y-ngx-components.mjs.map +1 -1
  29. package/locales/de.po +147 -16
  30. package/locales/es.po +143 -11
  31. package/locales/fr.po +459 -324
  32. package/locales/ja_JP.po +143 -11
  33. package/locales/ko.po +143 -11
  34. package/locales/locales.pot +139 -10
  35. package/locales/nl.po +143 -11
  36. package/locales/pl.po +143 -11
  37. package/locales/pt_BR.po +143 -11
  38. package/locales/zh_CN.po +143 -11
  39. package/locales/zh_TW.po +143 -11
  40. package/package.json +1 -1
  41. package/types/c8y-ngx-components-ai-agent-chat.d.ts +111 -4
  42. package/types/c8y-ngx-components-ai-agent-chat.d.ts.map +1 -1
  43. package/types/c8y-ngx-components-ai-agents-html.d.ts.map +1 -1
  44. package/types/c8y-ngx-components-ai-agents-scada.d.ts.map +1 -1
  45. package/types/c8y-ngx-components-ai-ai-chat.d.ts +224 -10
  46. package/types/c8y-ngx-components-ai-ai-chat.d.ts.map +1 -1
  47. package/types/c8y-ngx-components-ai.d.ts +176 -6
  48. package/types/c8y-ngx-components-ai.d.ts.map +1 -1
  49. package/types/c8y-ngx-components-context-dashboard.d.ts.map +1 -1
  50. package/types/c8y-ngx-components-datapoint-explorer-view.d.ts +7 -2
  51. package/types/c8y-ngx-components-datapoint-explorer-view.d.ts.map +1 -1
  52. package/types/c8y-ngx-components-datapoint-selector.d.ts +63 -50
  53. package/types/c8y-ngx-components-datapoint-selector.d.ts.map +1 -1
  54. package/types/c8y-ngx-components-echart.d.ts +12 -0
  55. package/types/c8y-ngx-components-echart.d.ts.map +1 -1
  56. package/types/c8y-ngx-components-time-context.d.ts +2 -0
  57. package/types/c8y-ngx-components-time-context.d.ts.map +1 -1
  58. package/types/c8y-ngx-components-widgets-implementations-scada.d.ts.map +1 -1
  59. package/types/c8y-ngx-components.d.ts +10 -1
  60. package/types/c8y-ngx-components.d.ts.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"c8y-ngx-components-ai.mjs","sources":["../../ai/ai.service.ts","../../ai/c8y-ngx-components-ai.ts"],"sourcesContent":["import { inject, Injectable } from '@angular/core';\nimport { FetchClient } from '@c8y/client';\nimport { Observable, Subscriber } from 'rxjs';\nimport {\n AgentDefinition,\n AgentHealthCheckResponse,\n AIAssistantMessage,\n AIMessage,\n AIMessagePart,\n AIStreamResponse,\n ClientAgentDefinition,\n ObjectAgentResponse,\n ToolCallPart\n} from './ai.model';\nimport { gettext } from '@c8y/ngx-components/gettext';\n\n// Internal implementation detail; maybe we don't even need this enum since\nexport enum DataStreamType {\n TEXT_DELTA = 'text-delta',\n TOOL_CALL = 'tool-call',\n TOOL_INPUT_START = 'tool-input-start',\n TOOL_INPUT_DELTA = 'tool-input-delta',\n TOOL_CALL_STREAMING = 'tool-call-streaming',\n TOOL_CALL_DELTA = 'tool-call-delta',\n TOOL_RESULT = 'tool-result',\n REASONING = 'reasoning',\n REASONING_DELTA = 'reasoning-delta',\n REDACTED_REASONING = 'redacted-reasoning',\n REASONING_SIGNATURE = 'reasoning-signature',\n FINISH_REASONING = 'finish-reasoning',\n FINISH = 'finish',\n FINISH_STEP = 'finish-step',\n ERROR = 'error',\n DATA = 'data',\n MESSAGE_ANNOTATIONS = 'message-annotations',\n SOURCE = 'source',\n FILE = 'file',\n STEP_START = 'start-step',\n STEP_FINISH = 'finish-step'\n}\n\n/** This service manages communication with the AI Agent Manager microservice, supporting\n * management of agents, and sending requests to the agents.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class AIService {\n private baseUrl = '/service/ai';\n private client: FetchClient;\n\n // nb: allowing the client to be passed in the constructor allows efficient unit testing without setting up the Angular TestBed\n constructor(client?: FetchClient) {\n this.client = client ?? inject(FetchClient);\n }\n\n /**\n * Creates or updates an agent.\n * @param def The agent definition\n */\n async createOrUpdateAgent(def: AgentDefinition): Promise<void> {\n const health = await this.getAgentHealth(def.name);\n let resource = `${this.baseUrl}/agent/${def.type}`;\n let method = 'POST';\n if (health.exists) {\n resource = `${this.baseUrl}/agent/${def.type}/${def.name}`;\n method = 'PUT';\n }\n const response = await this.client.fetch(resource, {\n body: JSON.stringify(def),\n method,\n headers: { 'Content-Type': 'application/json' }\n });\n\n if (!response.ok) {\n throw new Error(`Failed to create agent: ${response.statusText}`);\n }\n }\n\n /**\n * Check if an agent exists and is ready for use.\n * @param name Agent name (optional)\n * @param fromApp The app context path to check for an agent. This can be used, if the agent should get distributed by the plugin (optional).\n * @returns Agent health check response.\n */\n async getAgentHealth(name = '', fromApp?: string): Promise<AgentHealthCheckResponse> {\n const response = await this.client.fetch(\n `${this.baseUrl}/agent/test/${name || crypto.randomUUID()}${fromApp ? `?fromApp=${fromApp}` : ''}`,\n {\n method: 'GET',\n headers: { 'Content-Type': 'application/json' }\n }\n );\n\n if (!response.ok) {\n return {\n status: response.status === 403 ? 'missing-permissions' : 'missing-microservice',\n exists: false,\n canCreate: false,\n isProviderConfigured: false,\n messages: response.status === 403 ? [] : [response.statusText]\n };\n }\n const json: AgentHealthCheckResponse = await response.json();\n if (!json.isProviderConfigured) {\n json.status = 'missing-provider';\n } else if (!json.exists) {\n json.status = 'missing-agent';\n } else {\n json.status = 'ready';\n }\n return json;\n }\n\n /**\n * Send a text message to the agent.\n * @param name Agent name\n * @param messages The message to send, including any previous message history.\n * Typically you should use `defaultPruneMessagesForAgent` or a custom function to prepare the message history\n * by removing unnecessary content such as large/old tool inputs/outputs.\n * @param variables Variables to include\n * @param fromApp The app context path to check for an agent. This can be used, if the agent should get distributed by the plugin (optional).\n * @returns Text response from the agent.\n */\n async text(\n name: string,\n messages: AIMessage[],\n variables: Record<string, unknown>,\n fromApp?: string\n ): Promise<string> {\n const parsedMessages = this.convertToAgentMessageFormat(messages);\n\n const data = this.client.fetch(\n `${this.baseUrl}/agent/text/${name}${fromApp ? `?fromApp=${fromApp}` : ''}`,\n {\n body: JSON.stringify({ messages: parsedMessages, variables }),\n method: 'POST',\n headers: { 'Content-Type': 'application/json' }\n }\n );\n\n const response = await data;\n if (!response.ok) {\n throw new Error(`Failed to talk with agent: ${response.statusText}`);\n }\n const text = await response.text();\n return text;\n }\n\n /**\n * Send messages to an object-type agent via the non-streaming test endpoint.\n * Object agents return a single structured JSON response rather than a stream.\n *\n * @param agent A ClientAgentDefinition with `snapshot: true` (required for test endpoint).\n * @param messages Messages to send\n * @param variables Variables to include\n * @param abortController An AbortController to cancel the request.\n * @returns The full response including the structured object and usage information.\n */\n async callObjectAgent(\n agent: string | ClientAgentDefinition,\n messages: AIMessage[],\n variables: Record<string, unknown>,\n abortController: AbortController\n ): Promise<ObjectAgentResponse> {\n const parsedMessages = this.convertToAgentMessageFormat(messages);\n const agentName = typeof agent === 'string' ? agent : agent.definition.name;\n const useTest = typeof agent !== 'string' && agent.snapshot;\n const baseUrl = useTest\n ? `${this.baseUrl}/agent/test/${typeof agent !== 'string' ? agent.definition.type : 'object'}`\n : `${this.baseUrl}/agent/${typeof agent !== 'string' ? agent.definition.type : 'object'}/${agentName}`;\n let body = JSON.stringify({ messages: parsedMessages, variables });\n if (useTest) {\n const agentCopy = {\n ...(agent as ClientAgentDefinition).definition\n };\n agentCopy.agent.messages = parsedMessages;\n agentCopy.agent.variables = variables;\n body = JSON.stringify(agentCopy);\n }\n\n const response = await this.client.fetch(`${baseUrl}?fullResponse=true`, {\n method: 'POST',\n body,\n headers: {\n ...this.client.defaultHeaders,\n 'content-type': 'application/json'\n },\n signal: abortController.signal\n });\n\n if (response.status > 300) {\n const data = await response.json();\n throw new Error(JSON.stringify(data, null, 2));\n }\n\n const data = await response.json();\n\n if (!('object' in data)) {\n throw new Error('Invalid response: missing required \"object\" field');\n }\n\n if (typeof data.object !== 'object' || data.object === null) {\n throw new Error('Invalid response: \"object\" field must be an object');\n }\n\n // Validate optional totalUsage field if present\n if (data.totalUsage !== undefined) {\n if (typeof data.totalUsage !== 'object' || data.totalUsage === null) {\n throw new Error('Invalid response: \"totalUsage\" must be an object');\n }\n }\n\n return data;\n }\n\n /**\n * Stream a text message to the agent.\n * @param agent Agent name or an agent definition.\n * @param messages The message to send, including any previous message history.\n * Typically you should use `defaultPruneMessagesForAgent` or a custom function to prepare the message history\n * by removing unnecessary content such as large/old tool inputs/outputs.\n * @param variables Variables to include\n * @param abortController An AbortController to cancel the request.\n * @param fromApp The app context path to check for an agent. This can be used, if the agent should get distributed by the plugin (optional).\n * @returns An observable that emits AIStreamResponse including partial `AIMessage` objects as they are received.\n * When additional useful metadata is available, this will be streamed with type indicating it is metadata.\n * The observable can be cancelled using the provided AbortController.\n * The observable will emit an error if the request fails or is aborted.\n * The observable will complete when the stream is finished.\n *\n * The messages sent to the agent can include special options:\n * - `hiddenContent`: If set, this content will be sent to the agent instead of the `content` field.\n * - `skipToLLM`: If set to true, this message will be skipped when sending to the agent.\n *\n * Example usage:\n * ```typescript\n * const abortController = new AbortController();\n * const messages: AIMessage[] = [\n * { role: 'user', content: 'Hello' },\n * { role: 'assistant', content: 'Hi there!' },\n * { role: 'user', content: 'Tell me a joke.', options: { hiddenContent: 'Tell me a joke about cats.' } }\n * ];\n * const observable = aiService.stream$('my-agent', messages, {}, abortController);\n * const subscription = observable.subscribe({\n * next: (response) => { console.log('Received message update:', response.message); },\n * error: (err) => console.error('Error:', err),\n * complete: () => console.log('Stream complete')\n * });\n *\n * // To cancel the request:\n * abortController.abort();\n * subscription.unsubscribe();\n * ```\n */\n async stream$(\n agent: string | ClientAgentDefinition,\n messages: AIMessage[],\n variables: { [key: string]: any },\n abortController: AbortController,\n fromApp?: string\n ): Promise<Observable<AIStreamResponse>> {\n const parsedMessages = this.convertToAgentMessageFormat(messages);\n\n const agentName = typeof agent === 'string' ? agent : agent.definition.name;\n const useTest = typeof agent !== 'string' && agent.snapshot;\n const baseUrl = useTest\n ? `${this.baseUrl}/agent/test/text`\n : `${this.baseUrl}/agent/text/${agentName}`;\n let body = JSON.stringify({ messages: parsedMessages, variables });\n if (useTest) {\n const agentCopy = {\n ...agent.definition\n };\n agentCopy.agent['messages'] = parsedMessages;\n agentCopy.agent['variables'] = variables;\n body = JSON.stringify(agentCopy);\n }\n\n const response = await this.client.fetch(\n `${baseUrl}?fullResponse=true${fromApp ? `&fromApp=${fromApp}` : ''}`,\n {\n method: 'POST',\n body,\n headers: {\n ...this.client.defaultHeaders,\n 'content-type': 'application/json',\n accept: 'text/event-stream'\n },\n signal: abortController.signal\n }\n );\n\n const stream = response.body;\n const decoder = new TextDecoder();\n\n return new Observable<AIStreamResponse>(observer => {\n if (response.status > 300) {\n response\n .json()\n .then(data => {\n observer.error(`Error communicating with server: ${JSON.stringify(data, null, 2)}`);\n })\n .catch(err => {\n observer.error(\n `Error communicating with server: HTTP ${response.status}: ${response.statusText}; ${err}`\n );\n });\n return;\n }\n\n if (!stream) {\n observer.error('Server error - no response body');\n return;\n }\n\n const reader = stream.getReader();\n const message: AIAssistantMessage = {\n role: 'assistant',\n content: []\n };\n\n const abortHandler = (e: Event) => {\n const reason = (e?.target as AbortSignal)?.reason || gettext('Aborted');\n reader.cancel();\n observer.error(new DOMException(reason, 'AbortError'));\n };\n\n abortController.signal.addEventListener('abort', abortHandler);\n\n let buffer = '';\n\n const read = () => {\n reader.read().then(({ done, value }) => {\n if (done) {\n if (buffer.trim()) this.processLine(buffer, observer, message); // process any remaining data\n observer.complete();\n return;\n }\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n\\n');\n buffer = lines.pop() || '';\n for (const line of lines) {\n if (line.trim()) this.processLine(line, observer, message);\n }\n read();\n });\n };\n\n read();\n return () => {\n abortController.signal.removeEventListener('abort', abortHandler);\n reader.cancel();\n };\n });\n }\n\n protected convertToAgentMessageFormat(messages: AIMessage[]): object[] {\n // We will need to rewrite this to include tool outputs soon (effectively this means targetting LanguageModelV*ToolResultOutput).\n // Once we have more fields than just role and content, we will need to convert between our format and\n // the Vercel format expected by the agent manager (e.g. steps->content parts)\n return messages.map(m => {\n if (m.role !== 'assistant') {\n return {\n role: m.role,\n content: m.content\n };\n }\n\n // For assistant messages, check if there's an object part\n const objectPart = m.content.find(\n (part): part is { type: 'object'; jsonContent: string } => part.type === 'object'\n );\n\n if (objectPart) {\n // If there's an object part, parse and send the JSON object as content\n return {\n role: m.role,\n content: objectPart.jsonContent\n };\n }\n\n // Otherwise, send text parts as joined string\n return {\n role: m.role,\n content: m.content\n .filter((part): part is { type: 'text'; text: string } => part.type === 'text')\n .map(part => part.text)\n .join('\\n\\n')\n };\n });\n }\n\n /**\n * Convert a tool output from the MCP/wire format (which is different/more compact than LanguageModelV3ToolResultOutput)\n * into our own standard representation, which can be roundtripped to the format we need to provide when making future requests.\n *\n * Handles different data types from Vercel's streaming API:\n * - Text: stored as simple string in output field\n * - JSON objects: stored as-is in output field\n * - Content arrays: stored in output field with outputType=\"content\" to enable roundtripping\n * - Single text in content array: unwrapped to simple string for simpler handling (and easier truncation)\n * - Errors: error flag set to true\n */\n protected convertStreamingToolOutputToToolCallPart(output: any, target: ToolCallPart) {\n if (!output) {\n return;\n }\n\n if (output.isError || output.type === 'error-text' || output.type === 'error-json')\n target.error = true;\n\n // Handle content array format from streaming API\n if (output.content && Array.isArray(output.content)) {\n // Single text element - unwrap to simple string for simplicity\n if (output.content.length === 1 && output.content[0].type === 'text') {\n target.output = output.content[0].text;\n return;\n }\n\n // Multiple elements or mixed types - preserve as content array\n target.output = output.content;\n target.outputType = 'content'; // Mark as content to enable roundtripping\n return;\n }\n\n // Plain string or structured (JSON-serializable) object - store as-is\n target.output = output;\n }\n\n /** Add the specified tool call info to the current step. If this toolCallId is already known,\n * updates it rather than adding a new one, since for UI rendering and compactness of data it's\n * easiest to just have one item per tool call.\n *\n * Returns the changed item.\n */\n private addToolCallInfo(\n type: ToolCallPart['type'],\n rawInfo: any,\n addTo: AIMessagePart[]\n ): ToolCallPart {\n // Vercel v4 seems to set this to \"id\" not \"toolCallId\" in some places despite doc to the contrary, so normalize it here\n if (!rawInfo.toolCallId) rawInfo.toolCallId = rawInfo.id;\n\n let existing: ToolCallPart | undefined = addTo.find(\n (tc): tc is ToolCallPart =>\n tc.type.startsWith('tool-') && (tc as ToolCallPart).toolCallId === rawInfo.toolCallId\n );\n\n if (existing) {\n existing.type = type;\n } else if (!existing) {\n existing = { type: type, toolName: rawInfo.toolName, toolCallId: rawInfo.toolCallId };\n addTo.push(existing);\n }\n if (rawInfo?.input) existing.input = rawInfo.input;\n if (rawInfo?.output) this.convertStreamingToolOutputToToolCallPart(rawInfo.output, existing);\n\n return existing;\n }\n\n /** Unpacks data from the Vercel Data Stream Protocol (sent by the Agent Manager over SSE) to update the message\n *\n * See streamText().fullStream() from https://ai-sdk.dev/docs/ai-sdk-ui/stream-protocol#data-stream-protocol\n *\n * This is similar to what the Vercel `toUIMessageStreamResponse` API does (though it'd need the agent manager to publish the\n * UIMessageStream which has a bit more - useful - data than what is included here).\n *\n * We always use the same parts object, to make it easier for consumers (eg. agent-chat)\n * to add items to the list and have them still there on the next update from this service.\n */\n private processLine(\n line: string,\n observer: Subscriber<AIStreamResponse>,\n message: AIAssistantMessage\n ) {\n if (!line.trim()) {\n return;\n }\n\n try {\n let data: any = {};\n let type = '';\n try {\n data = JSON.parse(line.replace('data: ', ''));\n type = data.type;\n } catch (e) {\n console.error('Error parsing line from AI response: ', line, e);\n return;\n }\n\n let lastPart = !message.content ? undefined : message.content[message.content.length - 1];\n\n switch (type) {\n case DataStreamType.STEP_START:\n if (data.request && data.request.body) {\n observer.next({\n message: message,\n changedPart: {\n type: 'response-metadata',\n model: data.request.body.model,\n systemPrompt: data.request.body.systemPrompt\n }\n });\n }\n // Don't add consecutive duplicate step bounaries\n if (!lastPart || lastPart.type !== 'step-start') {\n message.content.push({ type: 'step-start' });\n observer.next({ message, changedPart: message.content[message.content.length - 1] });\n }\n\n return;\n\n case DataStreamType.REASONING_DELTA:\n const reasoning = data.text;\n if (!reasoning) return;\n if (lastPart?.type === 'reasoning') {\n lastPart.text += reasoning;\n } else {\n lastPart = { type: 'reasoning', text: reasoning };\n message.content.push(lastPart);\n }\n observer.next({ message, changedPart: lastPart });\n return;\n\n case DataStreamType.TEXT_DELTA:\n const text = data.textDelta || data.text;\n if (!text) return;\n if (lastPart?.type === 'text') {\n lastPart.text += text;\n } else {\n lastPart = { type: 'text', text: text };\n message.content.push(lastPart);\n }\n observer.next({ message, changedPart: lastPart });\n return;\n\n case DataStreamType.TOOL_INPUT_START:\n observer.next({\n message,\n changedPart: this.addToolCallInfo('tool-input-streaming', data, message.content)\n });\n return;\n\n case DataStreamType.TOOL_CALL:\n observer.next({\n message,\n changedPart: this.addToolCallInfo('tool-executing', data, message.content)\n });\n return;\n\n case DataStreamType.TOOL_RESULT:\n observer.next({\n message,\n changedPart: this.addToolCallInfo('tool-result', data, message.content)\n });\n return;\n\n case DataStreamType.FINISH:\n message.finishReason = data.finishReason; // FUTURE could be anything, may not match the options in AIMessage\n message.usage = data.totalUsage;\n observer.next({ message, changedPart: undefined });\n observer.complete();\n return;\n\n case DataStreamType.ERROR:\n message.finishReason = 'error';\n observer.next({ message, changedPart: undefined });\n observer.error(data?.message || data?.errorText || data);\n // Error is instead of completing the stream\n return;\n\n // Should we also handle other types such as \"abort\"?\n }\n } catch (e) {\n observer.error(e);\n }\n }\n}\n\n/**\n * The default implementation of for reducing the size of the message history so it is ready to be sent to the LLM agent.\n *\n * This is important since old tool inputs and outputs can be very large and fill up the agent's context window.\n *\n * Implements `pruneMessagesFunction`.\n *\n * When sending an AI request you can provide your own function instead of using this one,\n * or you can write your own function that calls this and adds extra logic,\n * for example to suppress specific tools from the AIMessage, or\n * retain only the final step text in multi-step responses, etc.\n *\n * The current default implementation preserves text content, but does not include any tool calls.\n * This may change in future releases.\n */\nexport function defaultPruneMessagesForAgent(messages: AIMessage[]): AIMessage[] {\n // When we change this to include tool calls, we should remove large inputs and truncate large and/or old outputs\n // to avoid too many tokens and context window consumption.\n // Some applications will want to entirely remove specific tool calls that have only transient use,\n // which can be done by providing their own pruneMessagesForAgent function.\n return messages.map(m => {\n if (m.role !== 'assistant') {\n return {\n role: m.role,\n content: m.content\n };\n }\n\n const textParts = m.content.filter(\n (part): part is { type: 'text'; text: string } => part.type === 'text'\n );\n const objectParts = m.content.filter(\n (part): part is { type: 'object'; jsonContent: string } => part.type === 'object'\n );\n\n const content: AIMessagePart[] = [];\n\n // Only add text part if there are text parts\n if (textParts.length > 0) {\n content.push({\n type: 'text',\n text: textParts.map(part => part.text).join('\\n\\n')\n });\n }\n\n // Preserve object parts for object agents\n content.push(...objectParts);\n\n return {\n role: m.role,\n content\n };\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"c8y-ngx-components-ai.mjs","sources":["../../ai/ai.service.ts","../../ai/ai-tool-approval-memory.service.ts","../../ai/cumulocity-api-request-label.ts","../../ai/c8y-ngx-components-ai.ts"],"sourcesContent":["import { inject, Injectable } from '@angular/core';\nimport { FetchClient } from '@c8y/client';\nimport { Observable, Subscriber } from 'rxjs';\nimport {\n AgentDefinition,\n AgentHealthCheckResponse,\n AIAssistantMessage,\n AIMessage,\n AIMessagePart,\n AIStreamResponse,\n ClientAgentDefinition,\n ObjectAgentResponse,\n ToolCallPart\n} from './ai.model';\nimport { gettext } from '@c8y/ngx-components/gettext';\n\n// Internal implementation detail; maybe we don't even need this enum since\nexport enum DataStreamType {\n TEXT_DELTA = 'text-delta',\n TOOL_CALL = 'tool-call',\n TOOL_INPUT_START = 'tool-input-start',\n TOOL_INPUT_DELTA = 'tool-input-delta',\n TOOL_CALL_STREAMING = 'tool-call-streaming',\n TOOL_CALL_DELTA = 'tool-call-delta',\n TOOL_RESULT = 'tool-result',\n TOOL_APPROVAL_REQUEST = 'tool-approval-request',\n REASONING = 'reasoning',\n REASONING_DELTA = 'reasoning-delta',\n REDACTED_REASONING = 'redacted-reasoning',\n REASONING_SIGNATURE = 'reasoning-signature',\n FINISH_REASONING = 'finish-reasoning',\n FINISH = 'finish',\n ERROR = 'error',\n DATA = 'data',\n MESSAGE_ANNOTATIONS = 'message-annotations',\n SOURCE = 'source',\n FILE = 'file',\n STEP_START = 'start-step',\n STEP_FINISH = 'finish-step'\n}\n\n/** This service manages communication with the AI Agent Manager microservice, supporting\n * management of agents, and sending requests to the agents.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class AIService {\n private baseUrl = '/service/ai';\n private client: FetchClient;\n\n // nb: allowing the client to be passed in the constructor allows efficient unit testing without setting up the Angular TestBed\n constructor(client?: FetchClient) {\n this.client = client ?? inject(FetchClient);\n }\n\n /**\n * Creates or updates an agent.\n * @param def The agent definition\n */\n async createOrUpdateAgent(def: AgentDefinition): Promise<void> {\n const health = await this.getAgentHealth(def.name);\n let resource = `${this.baseUrl}/agent/${def.type}`;\n let method = 'POST';\n if (health.exists) {\n resource = `${this.baseUrl}/agent/${def.type}/${def.name}`;\n method = 'PUT';\n }\n const response = await this.client.fetch(resource, {\n body: JSON.stringify(def),\n method,\n headers: { 'Content-Type': 'application/json' }\n });\n\n if (!response.ok) {\n const detail = await response.text().catch(() => '');\n throw new Error(\n `Failed to create agent: ${response.statusText}${detail ? ` - ${detail}` : ''}`\n );\n }\n }\n\n /**\n * Check if an agent exists and is ready for use.\n * @param name Agent name (optional)\n * @param fromApp The app context path to check for an agent. This can be used, if the agent should get distributed by the plugin (optional).\n * @returns Agent health check response.\n */\n async getAgentHealth(name = '', fromApp?: string): Promise<AgentHealthCheckResponse> {\n const response = await this.client.fetch(\n `${this.baseUrl}/agent/test/${name || crypto.randomUUID()}${fromApp ? `?fromApp=${fromApp}` : ''}`,\n {\n method: 'GET',\n headers: { 'Content-Type': 'application/json' }\n }\n );\n\n if (!response.ok) {\n return {\n status: response.status === 403 ? 'missing-permissions' : 'missing-microservice',\n exists: false,\n canCreate: false,\n isProviderConfigured: false,\n messages: response.status === 403 ? [] : [response.statusText]\n };\n }\n const json: AgentHealthCheckResponse = await response.json();\n if (!json.isProviderConfigured) {\n json.status = 'missing-provider';\n } else if (!json.exists) {\n json.status = 'missing-agent';\n } else {\n json.status = 'ready';\n }\n return json;\n }\n\n /**\n * Send a text message to the agent.\n * @param name Agent name\n * @param messages The message to send, including any previous message history.\n * Typically you should use `defaultPruneMessagesForAgent` or a custom function to prepare the message history\n * by removing unnecessary content such as large/old tool inputs/outputs.\n * @param variables Variables to include\n * @param fromApp The app context path to check for an agent. This can be used, if the agent should get distributed by the plugin (optional).\n * @returns Text response from the agent.\n */\n async text(\n name: string,\n messages: AIMessage[],\n variables: Record<string, unknown>,\n fromApp?: string\n ): Promise<string> {\n const parsedMessages = this.convertToAgentMessageFormat(messages);\n\n const data = this.client.fetch(\n `${this.baseUrl}/agent/text/${name}${fromApp ? `?fromApp=${fromApp}` : ''}`,\n {\n body: JSON.stringify({ messages: parsedMessages, variables }),\n method: 'POST',\n headers: { 'Content-Type': 'application/json' }\n }\n );\n\n const response = await data;\n if (!response.ok) {\n throw new Error(`Failed to talk with agent: ${response.statusText}`);\n }\n const text = await response.text();\n return text;\n }\n\n /**\n * Send messages to an object-type agent via the non-streaming test endpoint.\n * Object agents return a single structured JSON response rather than a stream.\n *\n * @param agent A ClientAgentDefinition with `snapshot: true` (required for test endpoint).\n * @param messages Messages to send\n * @param variables Variables to include\n * @param abortController An AbortController to cancel the request.\n * @returns The full response including the structured object and usage information.\n */\n async callObjectAgent(\n agent: string | ClientAgentDefinition,\n messages: AIMessage[],\n variables: Record<string, unknown>,\n abortController: AbortController\n ): Promise<ObjectAgentResponse> {\n const parsedMessages = this.convertToAgentMessageFormat(messages);\n const agentName = typeof agent === 'string' ? agent : agent.definition.name;\n const useTest = typeof agent !== 'string' && agent.snapshot;\n const baseUrl = useTest\n ? `${this.baseUrl}/agent/test/${typeof agent !== 'string' ? agent.definition.type : 'object'}`\n : `${this.baseUrl}/agent/${typeof agent !== 'string' ? agent.definition.type : 'object'}/${agentName}`;\n let body = JSON.stringify({ messages: parsedMessages, variables });\n if (useTest) {\n const agentCopy = {\n ...(agent as ClientAgentDefinition).definition\n };\n agentCopy.agent.messages = parsedMessages;\n agentCopy.agent.variables = variables;\n body = JSON.stringify(agentCopy);\n }\n\n const response = await this.client.fetch(`${baseUrl}?fullResponse=true`, {\n method: 'POST',\n body,\n headers: {\n ...this.client.defaultHeaders,\n 'content-type': 'application/json'\n },\n signal: abortController.signal\n });\n\n if (response.status > 300) {\n const data = await response.json();\n throw new Error(JSON.stringify(data, null, 2));\n }\n\n const data = await response.json();\n\n if (!('object' in data)) {\n throw new Error('Invalid response: missing required \"object\" field');\n }\n\n if (typeof data.object !== 'object' || data.object === null) {\n throw new Error('Invalid response: \"object\" field must be an object');\n }\n\n // Validate optional totalUsage field if present\n if (data.totalUsage !== undefined) {\n if (typeof data.totalUsage !== 'object' || data.totalUsage === null) {\n throw new Error('Invalid response: \"totalUsage\" must be an object');\n }\n }\n\n return data;\n }\n\n /**\n * Stream a text message to the agent.\n * @param agent Agent name or an agent definition.\n * @param messages The message to send, including any previous message history.\n * Typically you should use `defaultPruneMessagesForAgent` or a custom function to prepare the message history\n * by removing unnecessary content such as large/old tool inputs/outputs.\n * @param variables Variables to include\n * @param abortController An AbortController to cancel the request.\n * @param fromApp The app context path to check for an agent. This can be used, if the agent should get distributed by the plugin (optional).\n * @returns An observable that emits AIStreamResponse including partial `AIMessage` objects as they are received.\n * When additional useful metadata is available, this will be streamed with type indicating it is metadata.\n * The observable can be cancelled using the provided AbortController.\n * The observable will emit an error if the request fails or is aborted.\n * The observable will complete when the stream is finished.\n *\n * The messages sent to the agent can include special options:\n * - `hiddenContent`: If set, this content will be sent to the agent instead of the `content` field.\n * - `skipToLLM`: If set to true, this message will be skipped when sending to the agent.\n *\n * Example usage:\n * ```typescript\n * const abortController = new AbortController();\n * const messages: AIMessage[] = [\n * { role: 'user', content: 'Hello' },\n * { role: 'assistant', content: 'Hi there!' },\n * { role: 'user', content: 'Tell me a joke.', options: { hiddenContent: 'Tell me a joke about cats.' } }\n * ];\n * const observable = aiService.stream$('my-agent', messages, {}, abortController);\n * const subscription = observable.subscribe({\n * next: (response) => { console.log('Received message update:', response.message); },\n * error: (err) => console.error('Error:', err),\n * complete: () => console.log('Stream complete')\n * });\n *\n * // To cancel the request:\n * abortController.abort();\n * subscription.unsubscribe();\n * ```\n */\n async stream$(\n agent: string | ClientAgentDefinition,\n messages: AIMessage[],\n variables: { [key: string]: any },\n abortController: AbortController,\n fromApp?: string\n ): Promise<Observable<AIStreamResponse>> {\n const parsedMessages = this.convertToAgentMessageFormat(messages);\n\n const agentName = typeof agent === 'string' ? agent : agent.definition.name;\n const useTest = typeof agent !== 'string' && agent.snapshot;\n const baseUrl = useTest\n ? `${this.baseUrl}/agent/test/text`\n : `${this.baseUrl}/agent/text/${agentName}`;\n let body = JSON.stringify({ messages: parsedMessages, variables });\n if (useTest) {\n const agentCopy = {\n ...agent.definition\n };\n agentCopy.agent['messages'] = parsedMessages;\n agentCopy.agent['variables'] = variables;\n body = JSON.stringify(agentCopy);\n }\n\n const response = await this.client.fetch(\n `${baseUrl}?fullResponse=true${fromApp ? `&fromApp=${fromApp}` : ''}`,\n {\n method: 'POST',\n body,\n headers: {\n ...this.client.defaultHeaders,\n 'content-type': 'application/json',\n accept: 'text/event-stream'\n },\n signal: abortController.signal\n }\n );\n\n const stream = response.body;\n const decoder = new TextDecoder();\n\n return new Observable<AIStreamResponse>(observer => {\n if (response.status > 300) {\n response\n .json()\n .then(data => {\n observer.error(`Error communicating with server: ${JSON.stringify(data, null, 2)}`);\n })\n .catch(err => {\n observer.error(\n `Error communicating with server: HTTP ${response.status}: ${response.statusText}; ${err}`\n );\n });\n return;\n }\n\n if (!stream) {\n observer.error('Server error - no response body');\n return;\n }\n\n const reader = stream.getReader();\n const message: AIAssistantMessage = {\n role: 'assistant',\n content: []\n };\n\n const abortHandler = (e: Event) => {\n const reason = (e?.target as AbortSignal)?.reason || gettext('Aborted');\n reader.cancel();\n observer.error(new DOMException(reason, 'AbortError'));\n };\n\n abortController.signal.addEventListener('abort', abortHandler);\n\n let buffer = '';\n\n const read = () => {\n reader.read().then(({ done, value }) => {\n if (done) {\n if (buffer.trim()) this.processLine(buffer, observer, message); // process any remaining data\n observer.complete();\n return;\n }\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n\\n');\n buffer = lines.pop() || '';\n for (const line of lines) {\n if (line.trim()) this.processLine(line, observer, message);\n }\n read();\n });\n };\n\n read();\n return () => {\n abortController.signal.removeEventListener('abort', abortHandler);\n reader.cancel();\n };\n });\n }\n\n protected convertToAgentMessageFormat(messages: AIMessage[]): object[] {\n // We will need to rewrite this to include tool outputs soon (effectively this means targetting LanguageModelV*ToolResultOutput).\n // Once we have more fields than just role and content, we will need to convert between our format and\n // the Vercel format expected by the agent manager (e.g. steps->content parts)\n\n // The result of an approved tool call streams in with the NEXT assistant message after the\n // resume, but on the wire it must sit next to its approval exchange (the agent strips\n // approval parts from the model prompt, so an exchange without a result leaves a dangling\n // tool call the model provider rejects). Index all results up front so\n // convertAssistantMessageWithApprovals can pull them into the right message.\n const resultsByToolCallId = new Map<string, ToolCallPart>();\n for (const m of messages) {\n if (m.role !== 'assistant') continue;\n for (const part of m.content) {\n if (part.type === 'tool-result') {\n resultsByToolCallId.set(part.toolCallId, part);\n }\n }\n }\n const serializedToolCallIds = new Set<string>();\n\n return messages.flatMap(m => {\n if (m.role !== 'assistant') {\n return [\n {\n role: m.role,\n content: m.content\n }\n ];\n }\n\n // For assistant messages, check if there's an object part\n const objectPart = m.content.find(\n (part): part is { type: 'object'; jsonContent: string } => part.type === 'object'\n );\n\n if (objectPart) {\n // If there's an object part, parse and send the JSON object as content\n return [\n {\n role: m.role,\n content: objectPart.jsonContent\n }\n ];\n }\n\n // Messages containing tool approvals must round-trip with full fidelity so the agent\n // can match the user's decision to the pending tool call.\n if (\n m.content.some(\n part => part.type === 'tool-approval-requested' || part.type === 'tool-approval-responded'\n )\n ) {\n return this.convertAssistantMessageWithApprovals(\n m,\n resultsByToolCallId,\n serializedToolCallIds\n );\n }\n\n // Otherwise, send text parts as joined string\n return [\n {\n role: m.role,\n content: m.content\n .filter((part): part is { type: 'text'; text: string } => part.type === 'text')\n .map(part => part.text)\n .join('\\n\\n')\n }\n ];\n });\n }\n\n /**\n * Converts an assistant message containing tool approval parts into the wire format expected by\n * the agent: an assistant message carrying `tool-call` and `tool-approval-request` parts, followed\n * (once the user has decided) by a `tool` role message carrying the matching `tool-approval-response`\n * parts.\n *\n * The agent strips approval parts from the prompt it sends to the model provider, so a *resolved*\n * exchange must also carry the call's outcome in its tool message: the executed result (found via\n * `resultsByToolCallId`, since it streams in with the following assistant message) or an\n * `execution-denied` marker. Each such result is serialized exactly once - `serializedToolCallIds`\n * tracks consumed calls so the copy stored in the following message is not emitted again as a\n * duplicate tool call.\n */\n private convertAssistantMessageWithApprovals(\n m: AIAssistantMessage,\n resultsByToolCallId: Map<string, ToolCallPart>,\n serializedToolCallIds: Set<string>\n ): object[] {\n const assistantContent: object[] = [];\n const toolContent: object[] = [];\n\n for (const part of m.content) {\n switch (part.type) {\n case 'text':\n assistantContent.push({ type: 'text', text: part.text });\n break;\n\n case 'tool-approval-requested':\n case 'tool-approval-responded':\n if (!part.approval) break;\n assistantContent.push({\n type: 'tool-call',\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n input: part.input ?? {}\n });\n assistantContent.push({\n type: 'tool-approval-request',\n approvalId: part.approval.approvalId,\n toolCallId: part.toolCallId\n });\n if (part.approval.approved !== undefined) {\n toolContent.push({\n type: 'tool-approval-response',\n approvalId: part.approval.approvalId,\n approved: part.approval.approved,\n ...(part.approval.reason ? { reason: part.approval.reason } : {})\n });\n if (!serializedToolCallIds.has(part.toolCallId)) {\n if (!part.approval.approved) {\n toolContent.push({\n type: 'tool-result',\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n output: {\n type: 'execution-denied',\n ...(part.approval.reason ? { reason: part.approval.reason } : {})\n }\n });\n serializedToolCallIds.add(part.toolCallId);\n } else {\n const result = resultsByToolCallId.get(part.toolCallId);\n if (result) {\n toolContent.push({\n type: 'tool-result',\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n output: this.convertToolResultOutputForAgent(result)\n });\n serializedToolCallIds.add(part.toolCallId);\n }\n // No result yet: this approval is the one triggering the resume,\n // and the agent executes the tool itself.\n }\n }\n }\n break;\n\n case 'tool-result':\n // Skip results already serialized next to their approval exchange in an earlier message\n if (serializedToolCallIds.has(part.toolCallId)) break;\n assistantContent.push({\n type: 'tool-call',\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n input: part.input ?? {}\n });\n toolContent.push({\n type: 'tool-result',\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n output: this.convertToolResultOutputForAgent(part)\n });\n break;\n\n default:\n // reasoning and step-start parts are not needed by the agent\n break;\n }\n }\n\n const result: object[] = [{ role: 'assistant', content: assistantContent }];\n if (toolContent.length > 0) {\n result.push({ role: 'tool', content: toolContent });\n }\n return result;\n }\n\n /** Converts a tool output stored in our format back to the LanguageModelV*ToolResultOutput wire format. */\n private convertToolResultOutputForAgent(part: ToolCallPart): { type: string; value: unknown } {\n if (part.outputType === 'content') {\n return { type: 'content', value: part.output };\n }\n if (part.error) {\n return typeof part.output === 'string'\n ? { type: 'error-text', value: part.output }\n : { type: 'error-json', value: part.output ?? null };\n }\n return typeof part.output === 'string'\n ? { type: 'text', value: part.output }\n : { type: 'json', value: part.output ?? null };\n }\n\n /**\n * Convert a tool output from the MCP/wire format (which is different/more compact than LanguageModelV3ToolResultOutput)\n * into our own standard representation, which can be roundtripped to the format we need to provide when making future requests.\n *\n * Handles different data types from Vercel's streaming API:\n * - Text: stored as simple string in output field\n * - JSON objects: stored as-is in output field\n * - Content arrays: stored in output field with outputType=\"content\" to enable roundtripping\n * - Single text in content array: unwrapped to simple string for simpler handling (and easier truncation)\n * - Errors: error flag set to true\n */\n protected convertStreamingToolOutputToToolCallPart(output: any, target: ToolCallPart) {\n if (!output) {\n return;\n }\n\n if (output.isError || output.type === 'error-text' || output.type === 'error-json')\n target.error = true;\n\n // Handle content array format from streaming API\n if (output.content && Array.isArray(output.content)) {\n // Single text element - unwrap to simple string for simplicity\n if (output.content.length === 1 && output.content[0].type === 'text') {\n target.output = output.content[0].text;\n return;\n }\n\n // Multiple elements or mixed types - preserve as content array\n target.output = output.content;\n target.outputType = 'content'; // Mark as content to enable roundtripping\n return;\n }\n\n // Plain string or structured (JSON-serializable) object - store as-is\n target.output = output;\n }\n\n /** Add the specified tool call info to the current step. If this toolCallId is already known,\n * updates it rather than adding a new one, since for UI rendering and compactness of data it's\n * easiest to just have one item per tool call.\n *\n * Returns the changed item.\n */\n private addToolCallInfo(\n type: ToolCallPart['type'],\n rawInfo: any,\n addTo: AIMessagePart[]\n ): ToolCallPart {\n // Vercel v4 seems to set this to \"id\" not \"toolCallId\" in some places despite doc to the contrary, so normalize it here\n if (!rawInfo.toolCallId) rawInfo.toolCallId = rawInfo.id;\n\n let existing: ToolCallPart | undefined = addTo.find(\n (tc): tc is ToolCallPart =>\n tc.type.startsWith('tool-') && (tc as ToolCallPart).toolCallId === rawInfo.toolCallId\n );\n\n if (existing) {\n existing.type = type;\n } else if (!existing) {\n existing = { type: type, toolName: rawInfo.toolName, toolCallId: rawInfo.toolCallId };\n addTo.push(existing);\n }\n if (rawInfo?.input) existing.input = rawInfo.input;\n if (rawInfo?.output) this.convertStreamingToolOutputToToolCallPart(rawInfo.output, existing);\n\n return existing;\n }\n\n /** Unpacks data from the Vercel Data Stream Protocol (sent by the Agent Manager over SSE) to update the message\n *\n * See streamText().fullStream() from https://ai-sdk.dev/docs/ai-sdk-ui/stream-protocol#data-stream-protocol\n *\n * This is similar to what the Vercel `toUIMessageStreamResponse` API does (though it'd need the agent manager to publish the\n * UIMessageStream which has a bit more - useful - data than what is included here).\n *\n * We always use the same parts object, to make it easier for consumers (eg. agent-chat)\n * to add items to the list and have them still there on the next update from this service.\n */\n private processLine(\n line: string,\n observer: Subscriber<AIStreamResponse>,\n message: AIAssistantMessage\n ) {\n if (!line.trim()) {\n return;\n }\n\n try {\n let data: any = {};\n let type = '';\n try {\n data = JSON.parse(line.replace('data: ', ''));\n type = data.type;\n } catch (e) {\n console.error('Error parsing line from AI response: ', line, e);\n return;\n }\n\n let lastPart = !message.content ? undefined : message.content[message.content.length - 1];\n\n switch (type) {\n case DataStreamType.STEP_START:\n if (data.request && data.request.body) {\n observer.next({\n message: message,\n changedPart: {\n type: 'response-metadata',\n model: data.request.body.model,\n systemPrompt: data.request.body.systemPrompt\n }\n });\n }\n // Don't add consecutive duplicate step bounaries\n if (!lastPart || lastPart.type !== 'step-start') {\n message.content.push({ type: 'step-start' });\n observer.next({ message, changedPart: message.content[message.content.length - 1] });\n }\n\n return;\n\n case DataStreamType.REASONING_DELTA:\n const reasoning = data.text;\n if (!reasoning) return;\n if (lastPart?.type === 'reasoning') {\n lastPart.text += reasoning;\n } else {\n lastPart = { type: 'reasoning', text: reasoning };\n message.content.push(lastPart);\n }\n observer.next({ message, changedPart: lastPart });\n return;\n\n case DataStreamType.TEXT_DELTA:\n const text = data.textDelta || data.text;\n if (!text) return;\n if (lastPart?.type === 'text') {\n lastPart.text += text;\n } else {\n lastPart = { type: 'text', text: text };\n message.content.push(lastPart);\n }\n observer.next({ message, changedPart: lastPart });\n return;\n\n case DataStreamType.TOOL_INPUT_START:\n observer.next({\n message,\n changedPart: this.addToolCallInfo('tool-input-streaming', data, message.content)\n });\n return;\n\n case DataStreamType.TOOL_CALL:\n observer.next({\n message,\n changedPart: this.addToolCallInfo('tool-executing', data, message.content)\n });\n return;\n\n case DataStreamType.TOOL_RESULT:\n observer.next({\n message,\n changedPart: this.addToolCallInfo('tool-result', data, message.content)\n });\n return;\n\n case DataStreamType.TOOL_APPROVAL_REQUEST: {\n // Emitted when a tool with `needsApproval` is called; the agent stops until the\n // conversation is resent with the user's decision (see convertAssistantMessageWithApprovals).\n const approvalPart = this.addToolCallInfo(\n 'tool-approval-requested',\n data.toolCall || data,\n message.content\n );\n approvalPart.approval = { approvalId: data.approvalId };\n observer.next({ message, changedPart: approvalPart });\n return;\n }\n\n case DataStreamType.FINISH:\n message.finishReason = data.finishReason; // FUTURE could be anything, may not match the options in AIMessage\n message.usage = data.totalUsage;\n observer.next({ message, changedPart: undefined });\n observer.complete();\n return;\n\n case DataStreamType.ERROR:\n message.finishReason = 'error';\n observer.next({ message, changedPart: undefined });\n observer.error(data?.message || data?.errorText || data);\n // Error is instead of completing the stream\n return;\n\n // Should we also handle other types such as \"abort\"?\n }\n } catch (e) {\n observer.error(e);\n }\n }\n}\n\n/**\n * The default implementation of for reducing the size of the message history so it is ready to be sent to the LLM agent.\n *\n * This is important since old tool inputs and outputs can be very large and fill up the agent's context window.\n *\n * Implements `pruneMessagesFunction`.\n *\n * When sending an AI request you can provide your own function instead of using this one,\n * or you can write your own function that calls this and adds extra logic,\n * for example to suppress specific tools from the AIMessage, or\n * retain only the final step text in multi-step responses, etc.\n *\n * The current default implementation preserves text content, but does not include any tool calls.\n * This may change in future releases.\n */\nexport function defaultPruneMessagesForAgent(messages: AIMessage[]): AIMessage[] {\n // When we change this to include tool calls, we should remove large inputs and truncate large and/or old outputs\n // to avoid too many tokens and context window consumption.\n // Some applications will want to entirely remove specific tool calls that have only transient use,\n // which can be done by providing their own pruneMessagesForAgent function.\n // Tool calls that went through an approval exchange must keep their results as well:\n // the wire format pairs each resolved approval with its result, so pruning the result\n // would leave the approved tool call dangling in the prompt sent to the model.\n const approvalToolCallIds = new Set<string>();\n for (const m of messages) {\n if (m.role !== 'assistant') continue;\n for (const part of m.content) {\n if (part.type === 'tool-approval-requested' || part.type === 'tool-approval-responded') {\n approvalToolCallIds.add(part.toolCallId);\n }\n }\n }\n\n return messages.map(m => {\n if (m.role !== 'assistant') {\n return {\n role: m.role,\n content: m.content\n };\n }\n\n const textParts = m.content.filter(\n (part): part is { type: 'text'; text: string } => part.type === 'text'\n );\n const objectParts = m.content.filter(\n (part): part is { type: 'object'; jsonContent: string } => part.type === 'object'\n );\n // Approval parts must survive pruning: the agent needs the pending tool call and the\n // user's decision to resume a conversation that stopped for approval.\n const approvalParts = m.content.filter(\n (part): part is ToolCallPart =>\n part.type === 'tool-approval-requested' ||\n part.type === 'tool-approval-responded' ||\n (part.type === 'tool-result' && approvalToolCallIds.has(part.toolCallId))\n );\n\n const content: AIMessagePart[] = [];\n\n // Only add text part if there are text parts\n if (textParts.length > 0) {\n content.push({\n type: 'text',\n text: textParts.map(part => part.text).join('\\n\\n')\n });\n }\n\n // Preserve object parts for object agents\n content.push(...objectParts);\n content.push(...approvalParts);\n\n return {\n role: m.role,\n content\n };\n });\n}\n","import { Injectable } from '@angular/core';\n\n/** The remembered approval decisions of one chat session. */\ninterface SessionApprovals {\n /** YOLO mode for this session: every tool of the conversation is approved automatically. */\n approveAll: boolean;\n /** Tool names the user chose to always approve within this session. */\n tools: Set<string>;\n}\n\n/**\n * Remembers the user's \"always approve\" decisions for tool calls that require human approval.\n *\n * Decisions are held in memory only and are scoped to a chat session: each chat component\n * instance identifies its conversation with a unique session ID, so approvals never outlive\n * the conversation they were given in. Navigating away and back, reopening a dialog, or\n * starting a new conversation creates a new session that prompts again. This applies both to\n * single tools (\"always approve this tool\") and to the session-wide YOLO mode\n * ({@link rememberAllTools}, \"always approve all tools\").\n *\n * Tools configured with `needsApproval` always prompt regardless of these preferences; that\n * is enforced by the chat component, since it requires the agent definition. The chat\n * component also offers a global \"approve all tools\" option persisted as a user preference,\n * which is not managed by this service.\n *\n * Only approvals are remembered, never denials.\n */\n@Injectable({ providedIn: 'root' })\nexport class AiToolApprovalMemoryService {\n /** Remembered approvals, keyed by chat session ID. */\n private readonly sessions = new Map<string, SessionApprovals>();\n private nextSessionId = 0;\n\n /**\n * Returns a new chat session ID, unique for the lifetime of the page. Chat components request\n * one per conversation and pass it to the other methods to scope their approvals.\n */\n newSessionId(): string {\n return `chat-session-${++this.nextSessionId}`;\n }\n\n /** Remembers that calls of the given tool are always approved within the given chat session. */\n rememberTool(sessionId: string, toolName: string): void {\n this.session(sessionId).tools.add(toolName);\n }\n\n /**\n * Enables YOLO mode for the given chat session: every tool of the conversation is approved\n * automatically, without prompting, until the conversation ends.\n */\n rememberAllTools(sessionId: string): void {\n this.session(sessionId).approveAll = true;\n }\n\n /** Whether the user chose to always approve the given tool within the given chat session. */\n isToolRemembered(sessionId: string, toolName: string): boolean {\n return this.sessions.get(sessionId)?.tools.has(toolName) ?? false;\n }\n\n /** Whether YOLO mode is enabled for the given chat session (see {@link rememberAllTools}). */\n isApproveAllToolsEnabled(sessionId: string): boolean {\n return this.sessions.get(sessionId)?.approveAll ?? false;\n }\n\n /** Forgets the remembered approvals of a chat session, e.g. when the conversation ends. */\n endSession(sessionId: string): void {\n this.sessions.delete(sessionId);\n }\n\n /** Forgets all remembered approvals of all sessions. */\n clear(): void {\n this.sessions.clear();\n }\n\n private session(sessionId: string): SessionApprovals {\n let session = this.sessions.get(sessionId);\n if (!session) {\n session = { approveAll: false, tools: new Set<string>() };\n this.sessions.set(sessionId, session);\n }\n return session;\n }\n}\n","import { TranslateService } from '@ngx-translate/core';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { ToolCallPart } from './ai.model';\n\n/** REST resource segments the `cumulocity-api-request` tool commonly queries, mapped to a readable plural noun. */\nconst RESOURCE_LABELS: Record<string, string> = {\n managedObjects: gettext('inventory objects'),\n alarms: gettext('alarms'),\n measurements: gettext('measurements'),\n events: gettext('events'),\n operations: gettext('operations'),\n users: gettext('users'),\n applications: gettext('applications'),\n identity: gettext('external IDs')\n};\n\n/** Common `fragmentType`/`type` filter values used to narrow an inventory query, mapped to a more specific noun than the generic \"inventory objects\" label. */\nconst FRAGMENT_TYPE_LABELS: Record<string, string> = {\n c8y_IsDevice: gettext('devices'),\n c8y_IsDeviceGroup: gettext('device groups'),\n c8y_IsAsset: gettext('assets')\n};\n\n/**\n * A `labelProvider` (see `ToolCallConfig`) for the `cumulocity-api-request` tool: the generic\n * Cumulocity REST query tool offered to AI agents to look up API data. For a tool call awaiting\n * approval, produces a human-readable summary of the query - e.g. \"Look up: alarms with status:\n * active\" -\n * instead of the raw `{ \"query\": \"/alarm/alarms?status=ACTIVE\" }`, so the user can judge the\n * request without reading the API path themselves.\n *\n * Only applies to the `tool-approval-requested`/`tool-approval-responded` states; for every other\n * state this returns `undefined` so the caller's own `executingLabel`/`completedLabel` is used\n * instead. It also returns `undefined` for any query it doesn't recognize, which keeps the generic\n * \"Tool cumulocity-api-request requires approval\" text and the auto-expanded raw input as a\n * fallback - recognizes the common read endpoints (inventory, alarms, measurements, events,\n * operations, users, applications, identity).\n *\n * Assumes the tool's `query` input is a REST path with no separate `method`/body fields, matching\n * its documented purpose of verifying/looking up API data.\n */\nexport function cumulocityApiRequestLabelProvider(\n tool: ToolCallPart,\n translateService: TranslateService\n): string | undefined {\n if (tool.type !== 'tool-approval-requested' && tool.type !== 'tool-approval-responded') {\n return undefined;\n }\n\n const query = (tool.input as { query?: string } | undefined)?.query;\n const summary = summarizeQuery(query, translateService);\n if (!summary) return undefined;\n\n if (tool.type === 'tool-approval-responded') {\n return translateService.instant(\n tool.approval?.approved ? gettext('Approved: {{summary}}') : gettext('Denied: {{summary}}'),\n { summary }\n );\n }\n return summary;\n}\n\nfunction summarizeQuery(\n query: string | undefined,\n translateService: TranslateService\n): string | undefined {\n if (!query) return undefined;\n\n const [path, search] = query.split('?');\n const resourceKey = path.split('/').find(segment => RESOURCE_LABELS[segment]);\n if (!resourceKey) return undefined;\n\n const params = new URLSearchParams(search || '');\n const fragmentType = params.get('fragmentType') || params.get('type');\n const resource = translateService.instant(\n (fragmentType && FRAGMENT_TYPE_LABELS[fragmentType]) || RESOURCE_LABELS[resourceKey]\n );\n const status = params.get('status');\n\n return status\n ? translateService.instant(gettext('Look up: {{resource}} with status: {{status}}'), {\n status: status.toLowerCase(),\n resource\n })\n : translateService.instant(gettext('Look up: {{resource}}'), { resource });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -2802,6 +2802,10 @@ class WidgetConfigComponent {
2802
2802
  });
2803
2803
  }
2804
2804
  async onEscapePress(event) {
2805
+ // A modal on top owns the key and closes only itself.
2806
+ if (document.body.classList.contains('modal-open')) {
2807
+ return;
2808
+ }
2805
2809
  if (this.drawerService.isTop(this.bottomDrawerRef)) {
2806
2810
  event.preventDefault();
2807
2811
  await this.close();
@@ -2840,7 +2844,9 @@ class WidgetConfigComponent {
2840
2844
  return (!widgetConfig ||
2841
2845
  (!widgetConfig.settings?.deviceTargetNotRequired &&
2842
2846
  !widgetConfig.device &&
2843
- !widgetConfig.settings?.noDeviceTarget));
2847
+ !widgetConfig.settings?.noDeviceTarget &&
2848
+ // device type dashboards should not require a device target, as the device is implied by the dashboard's context
2849
+ !this.mo?.c8y_Dashboard?.deviceType));
2844
2850
  }
2845
2851
  async save() {
2846
2852
  const canSave = await this.widgetConfigService.canSave();