opencode/patches/@ai-sdk%2Fmistral@3.0.51.patch

709 lines
27 KiB
Diff

diff --git a/dist/index.d.mts b/dist/index.d.mts
index 1bde0b9f8cbe6771a52c1041095c9dddfe8e5b6c..0ca2ffb2a0c9327aed5ddcf0004500dc8b42569f 100644
--- a/dist/index.d.mts
+++ b/dist/index.d.mts
@@ -14,6 +14,7 @@ declare const mistralLanguageModelOptions: z.ZodObject<{
none: "none";
high: "high";
}>>;
+ promptCacheKey: z.ZodOptional<z.ZodString>;
}, z.core.$strip>;
type MistralLanguageModelOptions = z.infer<typeof mistralLanguageModelOptions>;
diff --git a/dist/index.d.ts b/dist/index.d.ts
index 1bde0b9f8cbe6771a52c1041095c9dddfe8e5b6c..0ca2ffb2a0c9327aed5ddcf0004500dc8b42569f 100644
--- a/dist/index.d.ts
+++ b/dist/index.d.ts
@@ -14,6 +14,7 @@ declare const mistralLanguageModelOptions: z.ZodObject<{
none: "none";
high: "high";
}>>;
+ promptCacheKey: z.ZodOptional<z.ZodString>;
}, z.core.$strip>;
type MistralLanguageModelOptions = z.infer<typeof mistralLanguageModelOptions>;
diff --git a/dist/index.js b/dist/index.js
index d3f904c12a1d582cc7b9e9a2d30273e1a8505b28..267f34e20ea392b7a85ad5259d72d50605a6f971 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -128,11 +128,14 @@ function convertToMistralChatMessages(prompt) {
}
case "assistant": {
let text = "";
+ const structuredContent = [];
+ let hasNativeReasoning = false;
const toolCalls = [];
for (const part of content) {
switch (part.type) {
case "text": {
text += part.text;
+ structuredContent.push({ type: "text", text: part.text });
break;
}
case "tool-call": {
@@ -148,6 +151,13 @@ function convertToMistralChatMessages(prompt) {
}
case "reasoning": {
text += part.text;
+ const native = part.providerOptions?.mistral?.thinking;
+ if (native?.type === "thinking") {
+ hasNativeReasoning = true;
+ structuredContent.push(native);
+ break;
+ }
+ structuredContent.push({ type: "text", text: part.text });
break;
}
default: {
@@ -159,7 +169,7 @@ function convertToMistralChatMessages(prompt) {
}
messages.push({
role: "assistant",
- content: text,
+ content: hasNativeReasoning ? structuredContent : text,
prefix: isLastMessage ? true : void 0,
tool_calls: toolCalls.length > 0 ? toolCalls : void 0
});
@@ -268,7 +278,8 @@ var mistralLanguageModelOptions = import_v4.z.object({
* - `'high'`: Enable reasoning
* - `'none'`: Disable reasoning
*/
- reasoningEffort: import_v4.z.enum(["high", "none"]).optional()
+ reasoningEffort: import_v4.z.enum(["high", "none"]).optional(),
+ promptCacheKey: import_v4.z.string().optional()
});
// src/mistral-error.ts
@@ -407,6 +418,7 @@ var MistralChatLanguageModel = class {
stop: stopSequences,
random_seed: seed,
reasoning_effort: options.reasoningEffort,
+ prompt_cache_key: options.promptCacheKey,
// response format:
response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? structuredOutputs && (responseFormat == null ? void 0 : responseFormat.schema) != null ? {
type: "json_schema",
@@ -465,9 +477,11 @@ var MistralChatLanguageModel = class {
for (const part of choice.message.content) {
if (part.type === "thinking") {
const reasoningText = extractReasoningContent(part.thinking);
- if (reasoningText.length > 0) {
- content.push({ type: "reasoning", text: reasoningText });
- }
+ content.push({
+ type: "reasoning",
+ text: reasoningText,
+ providerMetadata: { mistral: { thinking: part } }
+ });
} else if (part.type === "text") {
if (part.text.length > 0) {
content.push({ type: "text", text: part.text });
@@ -528,6 +542,7 @@ var MistralChatLanguageModel = class {
let isFirstChunk = true;
let activeText = false;
let activeReasoningId = null;
+ let activeThinking = null;
const generateId2 = this.generateId;
return {
stream: response.pipeThrough(
@@ -561,18 +576,19 @@ var MistralChatLanguageModel = class {
for (const part of delta.content) {
if (part.type === "thinking") {
const reasoningDelta = extractReasoningContent(part.thinking);
- if (reasoningDelta.length > 0) {
- if (activeReasoningId == null) {
- if (activeText) {
- controller.enqueue({ type: "text-end", id: "0" });
- activeText = false;
- }
- activeReasoningId = generateId2();
- controller.enqueue({
- type: "reasoning-start",
- id: activeReasoningId
- });
+ activeThinking = mergeThinking(activeThinking, part);
+ if (activeReasoningId == null) {
+ if (activeText) {
+ controller.enqueue({ type: "text-end", id: "0" });
+ activeText = false;
}
+ activeReasoningId = generateId2();
+ controller.enqueue({
+ type: "reasoning-start",
+ id: activeReasoningId
+ });
+ }
+ if (reasoningDelta.length > 0) {
controller.enqueue({
type: "reasoning-delta",
id: activeReasoningId,
@@ -587,9 +603,11 @@ var MistralChatLanguageModel = class {
if (activeReasoningId != null) {
controller.enqueue({
type: "reasoning-end",
- id: activeReasoningId
+ id: activeReasoningId,
+ providerMetadata: { mistral: { thinking: activeThinking } }
});
activeReasoningId = null;
+ activeThinking = null;
}
controller.enqueue({ type: "text-start", id: "0" });
activeText = true;
@@ -638,7 +656,8 @@ var MistralChatLanguageModel = class {
if (activeReasoningId != null) {
controller.enqueue({
type: "reasoning-end",
- id: activeReasoningId
+ id: activeReasoningId,
+ providerMetadata: { mistral: { thinking: activeThinking } }
});
}
if (activeText) {
@@ -660,6 +679,13 @@ var MistralChatLanguageModel = class {
function extractReasoningContent(thinking) {
return thinking.filter((chunk) => chunk.type === "text").map((chunk) => chunk.text).join("");
}
+function mergeThinking(current, next) {
+ if (current === null) return { ...next, thinking: [...next.thinking] };
+ current.thinking.push(...next.thinking);
+ if (next.closed !== void 0) current.closed = next.closed;
+ if (next.signature !== void 0) current.signature = next.signature;
+ return current;
+}
function extractTextContent(content) {
if (typeof content === "string") {
return content;
@@ -686,6 +712,30 @@ function extractTextContent(content) {
}
return textContent.length ? textContent.join("") : void 0;
}
+var mistralThinkingContentSchema = import_v43.z.discriminatedUnion("type", [
+ import_v43.z.object({
+ type: import_v43.z.literal("text"),
+ text: import_v43.z.string()
+ }),
+ import_v43.z.object({
+ type: import_v43.z.literal("tool_reference"),
+ tool: import_v43.z.string(),
+ title: import_v43.z.string(),
+ url: import_v43.z.string().nullish(),
+ favicon: import_v43.z.string().nullish(),
+ description: import_v43.z.string().nullish()
+ }),
+ import_v43.z.object({
+ type: import_v43.z.literal("reference"),
+ reference_ids: import_v43.z.array(import_v43.z.union([import_v43.z.string(), import_v43.z.number().int()]))
+ })
+]);
+var mistralThinkChunkSchema = import_v43.z.object({
+ type: import_v43.z.literal("thinking"),
+ thinking: import_v43.z.array(mistralThinkingContentSchema),
+ closed: import_v43.z.boolean().optional(),
+ signature: import_v43.z.string().nullish()
+});
var mistralContentSchema = import_v43.z.union([
import_v43.z.string(),
import_v43.z.array(
@@ -708,15 +758,7 @@ var mistralContentSchema = import_v43.z.union([
type: import_v43.z.literal("reference"),
reference_ids: import_v43.z.array(import_v43.z.union([import_v43.z.string(), import_v43.z.number()]))
}),
- import_v43.z.object({
- type: import_v43.z.literal("thinking"),
- thinking: import_v43.z.array(
- import_v43.z.object({
- type: import_v43.z.literal("text"),
- text: import_v43.z.string()
- })
- )
- })
+ mistralThinkChunkSchema
])
)
]).nullish();
diff --git a/dist/index.mjs b/dist/index.mjs
index d2eff622c1b84a96bdeb4012cb0206a33012a04d..3bff11ddd6136ada45809568828cbc8f2493a42a 100644
--- a/dist/index.mjs
+++ b/dist/index.mjs
@@ -116,11 +116,14 @@ function convertToMistralChatMessages(prompt) {
}
case "assistant": {
let text = "";
+ const structuredContent = [];
+ let hasNativeReasoning = false;
const toolCalls = [];
for (const part of content) {
switch (part.type) {
case "text": {
text += part.text;
+ structuredContent.push({ type: "text", text: part.text });
break;
}
case "tool-call": {
@@ -136,6 +139,13 @@ function convertToMistralChatMessages(prompt) {
}
case "reasoning": {
text += part.text;
+ const native = part.providerOptions?.mistral?.thinking;
+ if (native?.type === "thinking") {
+ hasNativeReasoning = true;
+ structuredContent.push(native);
+ break;
+ }
+ structuredContent.push({ type: "text", text: part.text });
break;
}
default: {
@@ -147,7 +157,7 @@ function convertToMistralChatMessages(prompt) {
}
messages.push({
role: "assistant",
- content: text,
+ content: hasNativeReasoning ? structuredContent : text,
prefix: isLastMessage ? true : void 0,
tool_calls: toolCalls.length > 0 ? toolCalls : void 0
});
@@ -256,7 +266,8 @@ var mistralLanguageModelOptions = z.object({
* - `'high'`: Enable reasoning
* - `'none'`: Disable reasoning
*/
- reasoningEffort: z.enum(["high", "none"]).optional()
+ reasoningEffort: z.enum(["high", "none"]).optional(),
+ promptCacheKey: z.string().optional()
});
// src/mistral-error.ts
@@ -397,6 +408,7 @@ var MistralChatLanguageModel = class {
stop: stopSequences,
random_seed: seed,
reasoning_effort: options.reasoningEffort,
+ prompt_cache_key: options.promptCacheKey,
// response format:
response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? structuredOutputs && (responseFormat == null ? void 0 : responseFormat.schema) != null ? {
type: "json_schema",
@@ -455,9 +467,11 @@ var MistralChatLanguageModel = class {
for (const part of choice.message.content) {
if (part.type === "thinking") {
const reasoningText = extractReasoningContent(part.thinking);
- if (reasoningText.length > 0) {
- content.push({ type: "reasoning", text: reasoningText });
- }
+ content.push({
+ type: "reasoning",
+ text: reasoningText,
+ providerMetadata: { mistral: { thinking: part } }
+ });
} else if (part.type === "text") {
if (part.text.length > 0) {
content.push({ type: "text", text: part.text });
@@ -518,6 +532,7 @@ var MistralChatLanguageModel = class {
let isFirstChunk = true;
let activeText = false;
let activeReasoningId = null;
+ let activeThinking = null;
const generateId2 = this.generateId;
return {
stream: response.pipeThrough(
@@ -551,18 +566,19 @@ var MistralChatLanguageModel = class {
for (const part of delta.content) {
if (part.type === "thinking") {
const reasoningDelta = extractReasoningContent(part.thinking);
- if (reasoningDelta.length > 0) {
- if (activeReasoningId == null) {
- if (activeText) {
- controller.enqueue({ type: "text-end", id: "0" });
- activeText = false;
- }
- activeReasoningId = generateId2();
- controller.enqueue({
- type: "reasoning-start",
- id: activeReasoningId
- });
+ activeThinking = mergeThinking(activeThinking, part);
+ if (activeReasoningId == null) {
+ if (activeText) {
+ controller.enqueue({ type: "text-end", id: "0" });
+ activeText = false;
}
+ activeReasoningId = generateId2();
+ controller.enqueue({
+ type: "reasoning-start",
+ id: activeReasoningId
+ });
+ }
+ if (reasoningDelta.length > 0) {
controller.enqueue({
type: "reasoning-delta",
id: activeReasoningId,
@@ -577,9 +593,11 @@ var MistralChatLanguageModel = class {
if (activeReasoningId != null) {
controller.enqueue({
type: "reasoning-end",
- id: activeReasoningId
+ id: activeReasoningId,
+ providerMetadata: { mistral: { thinking: activeThinking } }
});
activeReasoningId = null;
+ activeThinking = null;
}
controller.enqueue({ type: "text-start", id: "0" });
activeText = true;
@@ -628,7 +646,8 @@ var MistralChatLanguageModel = class {
if (activeReasoningId != null) {
controller.enqueue({
type: "reasoning-end",
- id: activeReasoningId
+ id: activeReasoningId,
+ providerMetadata: { mistral: { thinking: activeThinking } }
});
}
if (activeText) {
@@ -650,6 +669,13 @@ var MistralChatLanguageModel = class {
function extractReasoningContent(thinking) {
return thinking.filter((chunk) => chunk.type === "text").map((chunk) => chunk.text).join("");
}
+function mergeThinking(current, next) {
+ if (current === null) return { ...next, thinking: [...next.thinking] };
+ current.thinking.push(...next.thinking);
+ if (next.closed !== void 0) current.closed = next.closed;
+ if (next.signature !== void 0) current.signature = next.signature;
+ return current;
+}
function extractTextContent(content) {
if (typeof content === "string") {
return content;
@@ -676,6 +702,30 @@ function extractTextContent(content) {
}
return textContent.length ? textContent.join("") : void 0;
}
+var mistralThinkingContentSchema = z3.discriminatedUnion("type", [
+ z3.object({
+ type: z3.literal("text"),
+ text: z3.string()
+ }),
+ z3.object({
+ type: z3.literal("tool_reference"),
+ tool: z3.string(),
+ title: z3.string(),
+ url: z3.string().nullish(),
+ favicon: z3.string().nullish(),
+ description: z3.string().nullish()
+ }),
+ z3.object({
+ type: z3.literal("reference"),
+ reference_ids: z3.array(z3.union([z3.string(), z3.number().int()]))
+ })
+]);
+var mistralThinkChunkSchema = z3.object({
+ type: z3.literal("thinking"),
+ thinking: z3.array(mistralThinkingContentSchema),
+ closed: z3.boolean().optional(),
+ signature: z3.string().nullish()
+});
var mistralContentSchema = z3.union([
z3.string(),
z3.array(
@@ -698,15 +748,7 @@ var mistralContentSchema = z3.union([
type: z3.literal("reference"),
reference_ids: z3.array(z3.union([z3.string(), z3.number()]))
}),
- z3.object({
- type: z3.literal("thinking"),
- thinking: z3.array(
- z3.object({
- type: z3.literal("text"),
- text: z3.string()
- })
- )
- })
+ mistralThinkChunkSchema
])
)
]).nullish();
diff --git a/src/convert-to-mistral-chat-messages.ts b/src/convert-to-mistral-chat-messages.ts
index 3c6914f8da615d7517bc43dd56198298d0a50247..8cd6f4c7577f746ef41e8a0aee682234c473667a 100644
--- a/src/convert-to-mistral-chat-messages.ts
+++ b/src/convert-to-mistral-chat-messages.ts
@@ -3,7 +3,11 @@ import {
type LanguageModelV3DataContent,
type LanguageModelV3Prompt,
} from '@ai-sdk/provider';
-import type { MistralPrompt } from './mistral-chat-prompt';
+import type {
+ MistralAssistantMessageContent,
+ MistralPrompt,
+ MistralThinkChunk,
+} from './mistral-chat-prompt';
import { convertToBase64 } from '@ai-sdk/provider-utils';
function formatFileUrl({
@@ -76,6 +80,8 @@ export function convertToMistralChatMessages(
case 'assistant': {
let text = '';
+ const structuredContent: Array<MistralAssistantMessageContent> = [];
+ let hasNativeReasoning = false;
const toolCalls: Array<{
id: string;
type: 'function';
@@ -86,6 +92,7 @@ export function convertToMistralChatMessages(
switch (part.type) {
case 'text': {
text += part.text;
+ structuredContent.push({ type: 'text', text: part.text });
break;
}
case 'tool-call': {
@@ -101,6 +108,14 @@ export function convertToMistralChatMessages(
}
case 'reasoning': {
text += part.text;
+ const native = part.providerOptions?.mistral
+ ?.thinking as MistralThinkChunk | undefined;
+ if (native?.type === 'thinking') {
+ hasNativeReasoning = true;
+ structuredContent.push(native);
+ break;
+ }
+ structuredContent.push({ type: 'text', text: part.text });
break;
}
default: {
@@ -113,7 +128,7 @@ export function convertToMistralChatMessages(
messages.push({
role: 'assistant',
- content: text,
+ content: hasNativeReasoning ? structuredContent : text,
prefix: isLastMessage ? true : undefined,
tool_calls: toolCalls.length > 0 ? toolCalls : undefined,
});
diff --git a/src/mistral-chat-language-model.ts b/src/mistral-chat-language-model.ts
index 7e4a7ab552f1b41b7074e1b3cada8a51d791268d..847d26f9dfe03572a969a122f8c96b8bbfda8066 100644
--- a/src/mistral-chat-language-model.ts
+++ b/src/mistral-chat-language-model.ts
@@ -122,6 +122,7 @@ export class MistralChatLanguageModel implements LanguageModelV3 {
stop: stopSequences,
random_seed: seed,
reasoning_effort: options.reasoningEffort,
+ prompt_cache_key: options.promptCacheKey,
// response format:
response_format:
@@ -201,9 +202,11 @@ export class MistralChatLanguageModel implements LanguageModelV3 {
for (const part of choice.message.content) {
if (part.type === 'thinking') {
const reasoningText = extractReasoningContent(part.thinking);
- if (reasoningText.length > 0) {
- content.push({ type: 'reasoning', text: reasoningText });
- }
+ content.push({
+ type: 'reasoning',
+ text: reasoningText,
+ providerMetadata: { mistral: { thinking: part } },
+ });
} else if (part.type === 'text') {
if (part.text.length > 0) {
content.push({ type: 'text', text: part.text });
@@ -278,6 +281,7 @@ export class MistralChatLanguageModel implements LanguageModelV3 {
let isFirstChunk = true;
let activeText = false;
let activeReasoningId: string | null = null;
+ let activeThinking: z.infer<typeof mistralThinkChunkSchema> | null = null;
const generateId = this.generateId;
@@ -326,20 +330,21 @@ export class MistralChatLanguageModel implements LanguageModelV3 {
for (const part of delta.content) {
if (part.type === 'thinking') {
const reasoningDelta = extractReasoningContent(part.thinking);
- if (reasoningDelta.length > 0) {
- if (activeReasoningId == null) {
- // end any active text before starting reasoning
- if (activeText) {
- controller.enqueue({ type: 'text-end', id: '0' });
- activeText = false;
- }
-
- activeReasoningId = generateId();
- controller.enqueue({
- type: 'reasoning-start',
- id: activeReasoningId,
- });
+ activeThinking = mergeThinking(activeThinking, part);
+ if (activeReasoningId == null) {
+ // end any active text before starting reasoning
+ if (activeText) {
+ controller.enqueue({ type: 'text-end', id: '0' });
+ activeText = false;
}
+
+ activeReasoningId = generateId();
+ controller.enqueue({
+ type: 'reasoning-start',
+ id: activeReasoningId,
+ });
+ }
+ if (reasoningDelta.length > 0) {
controller.enqueue({
type: 'reasoning-delta',
id: activeReasoningId,
@@ -357,8 +362,12 @@ export class MistralChatLanguageModel implements LanguageModelV3 {
controller.enqueue({
type: 'reasoning-end',
id: activeReasoningId,
+ providerMetadata: {
+ mistral: { thinking: activeThinking },
+ },
});
activeReasoningId = null;
+ activeThinking = null;
}
controller.enqueue({ type: 'text-start', id: '0' });
activeText = true;
@@ -416,6 +425,9 @@ export class MistralChatLanguageModel implements LanguageModelV3 {
controller.enqueue({
type: 'reasoning-end',
id: activeReasoningId,
+ providerMetadata: {
+ mistral: { thinking: activeThinking },
+ },
});
}
if (activeText) {
@@ -437,7 +449,7 @@ export class MistralChatLanguageModel implements LanguageModelV3 {
}
function extractReasoningContent(
- thinking: Array<{ type: string; text: string }>,
+ thinking: Array<z.infer<typeof mistralThinkingContentSchema>>,
) {
return thinking
.filter(chunk => chunk.type === 'text')
@@ -445,6 +457,17 @@ function extractReasoningContent(
.join('');
}
+function mergeThinking(
+ current: z.infer<typeof mistralThinkChunkSchema> | null,
+ next: z.infer<typeof mistralThinkChunkSchema>,
+) {
+ if (current === null) return { ...next, thinking: [...next.thinking] };
+ current.thinking.push(...next.thinking);
+ if (next.closed !== undefined) current.closed = next.closed;
+ if (next.signature !== undefined) current.signature = next.signature;
+ return current;
+}
+
function extractTextContent(content: z.infer<typeof mistralContentSchema>) {
if (typeof content === 'string') {
return content;
@@ -478,6 +501,32 @@ function extractTextContent(content: z.infer<typeof mistralContentSchema>) {
return textContent.length ? textContent.join('') : undefined;
}
+const mistralThinkingContentSchema = z.discriminatedUnion('type', [
+ z.object({
+ type: z.literal('text'),
+ text: z.string(),
+ }),
+ z.object({
+ type: z.literal('tool_reference'),
+ tool: z.string(),
+ title: z.string(),
+ url: z.string().nullish(),
+ favicon: z.string().nullish(),
+ description: z.string().nullish(),
+ }),
+ z.object({
+ type: z.literal('reference'),
+ reference_ids: z.array(z.union([z.string(), z.number().int()])),
+ }),
+]);
+
+const mistralThinkChunkSchema = z.object({
+ type: z.literal('thinking'),
+ thinking: z.array(mistralThinkingContentSchema),
+ closed: z.boolean().optional(),
+ signature: z.string().nullish(),
+});
+
const mistralContentSchema = z
.union([
z.string(),
@@ -501,15 +550,7 @@ const mistralContentSchema = z
type: z.literal('reference'),
reference_ids: z.array(z.union([z.string(), z.number()])),
}),
- z.object({
- type: z.literal('thinking'),
- thinking: z.array(
- z.object({
- type: z.literal('text'),
- text: z.string(),
- }),
- ),
- }),
+ mistralThinkChunkSchema,
]),
),
])
diff --git a/src/mistral-chat-options.ts b/src/mistral-chat-options.ts
index 54b29c08517d348995b6ca093b11160e453d5c8b..de30c3e7d924889339e38b1067cb26e9ada05d11 100644
--- a/src/mistral-chat-options.ts
+++ b/src/mistral-chat-options.ts
@@ -64,6 +64,11 @@ export const mistralLanguageModelOptions = z.object({
* - `'none'`: Disable reasoning
*/
reasoningEffort: z.enum(['high', 'none']).optional(),
+
+ /**
+ * A stable identifier used to route requests with shared prompt prefixes.
+ */
+ promptCacheKey: z.string().optional(),
});
export type MistralLanguageModelOptions = z.infer<
diff --git a/src/mistral-chat-prompt.ts b/src/mistral-chat-prompt.ts
index 13f1dced55ac4be084128127a57fbdd58115bc28..172b11dde3dd326c2f3befd99237474ed8c79285 100644
--- a/src/mistral-chat-prompt.ts
+++ b/src/mistral-chat-prompt.ts
@@ -23,7 +23,7 @@ export type MistralUserMessageContent =
export interface MistralAssistantMessage {
role: 'assistant';
- content: string;
+ content: string | Array<MistralAssistantMessageContent>;
prefix?: boolean;
tool_calls?: Array<{
id: string;
@@ -32,6 +32,29 @@ export interface MistralAssistantMessage {
}>;
}
+export type MistralAssistantMessageContent =
+ | { type: 'text'; text: string }
+ | MistralThinkChunk;
+
+export type MistralThinkChunk = {
+ type: 'thinking';
+ thinking: Array<MistralThinkingContent>;
+ closed?: boolean;
+ signature?: string | null;
+};
+
+export type MistralThinkingContent =
+ | { type: 'text'; text: string }
+ | {
+ type: 'tool_reference';
+ tool: string;
+ title: string;
+ url?: string | null;
+ favicon?: string | null;
+ description?: string | null;
+ }
+ | { type: 'reference'; reference_ids: Array<string | number> };
+
export interface MistralToolMessage {
role: 'tool';
name: string;