(messages: GenAIAgentMessage[])
| 119 | } |
| 120 | |
| 121 | function marshalAgentMessages(messages: GenAIAgentMessage[]): string | undefined { |
| 122 | if (messages.length === 0) return undefined |
| 123 | const json = JSON.stringify(messages) |
| 124 | if (json.length <= GENAI_MESSAGE_ATTR_MAX_BYTES) return json |
| 125 | // Simple tail-preserving truncation: drop from the front until we |
| 126 | // fit. Matches the Go side's behavior. The last message is |
| 127 | // usually the most diagnostic for span-level outcome. |
| 128 | let remaining = messages.slice() |
| 129 | while (remaining.length > 1) { |
| 130 | remaining = remaining.slice(1) |
| 131 | const candidate = JSON.stringify(remaining) |
| 132 | if (candidate.length <= GENAI_MESSAGE_ATTR_MAX_BYTES) return candidate |
| 133 | } |
| 134 | // Single message still over cap — truncate the text part in place |
| 135 | // with a marker so the partial content is still readable. |
| 136 | const only = remaining[0] |
| 137 | for (const part of only.parts) { |
| 138 | if (part.type === 'text' && part.content) { |
| 139 | const headroom = GENAI_MESSAGE_ATTR_MAX_BYTES - 1024 |
| 140 | if (part.content.length > headroom) { |
| 141 | part.content = `${part.content.slice(0, headroom)}\n\n[truncated: capture cap ${GENAI_MESSAGE_ATTR_MAX_BYTES} bytes]` |
| 142 | } |
| 143 | } |
| 144 | } |
| 145 | const final = JSON.stringify([only]) |
| 146 | return final.length <= GENAI_MESSAGE_ATTR_MAX_BYTES ? final : undefined |
| 147 | } |
| 148 | |
| 149 | interface CopilotAgentInputMessages { |
| 150 | userMessage?: string |
no outgoing calls
no test coverage detected