# Mistral Client

Interact with Mistral AI's APIs for chat completions, embeddings, and code generation.

## Methods

| Method                                   | Description                                         |
| ---------------------------------------- | --------------------------------------------------- |
| `apiRequest(options, schema, metadata?)` | Make any Mistral API request with schema validation |

## Usage

### Step 1: List Available Models

Model availability varies by account and API plan. Before making requests, validate which models you can access:

```typescript
import { api, z, mistral } from "@superblocksteam/sdk-api";

// Integration ID from the integrations panel
const PROD_MISTRAL = "a1b2c3d4-5678-90ab-cdef-mistral00001";

const ModelsResponseSchema = z.object({
  data: z.array(
    z.object({
      id: z.string(),
      object: z.string(),
    }),
  ),
});

const models = await ctx.integrations.mistral.apiRequest(
  {
    method: "GET",
    path: "/models",
  },
  { response: ModelsResponseSchema },
);

// Use a model ID from the response in subsequent requests
const availableModelId = models.data[0]?.id;
```

### Chat Completion

```typescript
const ChatCompletionResponseSchema = z.object({
  id: z.string(),
  object: z.string(),
  created: z.number(),
  model: z.string(),
  choices: z.array(
    z.object({
      index: z.number(),
      message: z.object({
        role: z.string(),
        content: z.string(),
      }),
      finish_reason: z.string(),
    }),
  ),
  usage: z.object({
    prompt_tokens: z.number(),
    completion_tokens: z.number(),
    total_tokens: z.number(),
  }),
});

export default api({
  integrations: {
    mistral: mistral(PROD_MISTRAL),
  },
  name: "MistralExample",
  input: z.object({
    prompt: z.string(),
  }),
  output: z.object({
    response: z.string(),
  }),
  async run(ctx, { prompt }) {
    const result = await ctx.integrations.mistral.apiRequest(
      {
        method: "POST",
        path: "/chat/completions",
        body: {
          model: "mistral-large-latest",
          messages: [{ role: "user", content: prompt }],
        },
      },
      { response: ChatCompletionResponseSchema },
    );

    return { response: result.choices[0]?.message.content ?? "" };
  },
});
```

### Using Different Models

```typescript
// Mistral Large - Most capable
const large = await ctx.integrations.mistral.apiRequest(
  {
    method: "POST",
    path: "/chat/completions",
    body: {
      model: "mistral-large-latest",
      messages: [{ role: "user", content: "Complex analysis..." }],
    },
  },
  { response: ChatCompletionResponseSchema },
);

// Mistral Medium - Balanced
const medium = await ctx.integrations.mistral.apiRequest(
  {
    method: "POST",
    path: "/chat/completions",
    body: {
      model: "mistral-medium-latest",
      messages: [{ role: "user", content: "General task..." }],
    },
  },
  { response: ChatCompletionResponseSchema },
);

// Mistral Small - Fast and efficient
const small = await ctx.integrations.mistral.apiRequest(
  {
    method: "POST",
    path: "/chat/completions",
    body: {
      model: "mistral-small-latest",
      messages: [{ role: "user", content: "Simple task..." }],
    },
  },
  { response: ChatCompletionResponseSchema },
);

// Codestral - Optimized for code
const codestral = await ctx.integrations.mistral.apiRequest(
  {
    method: "POST",
    path: "/chat/completions",
    body: {
      model: "codestral-latest",
      messages: [{ role: "user", content: "Write a function to..." }],
    },
  },
  { response: ChatCompletionResponseSchema },
);
```

### Generate Embeddings

```typescript
const EmbeddingsResponseSchema = z.object({
  id: z.string(),
  object: z.string(),
  data: z.array(
    z.object({
      object: z.string(),
      embedding: z.array(z.number()),
      index: z.number(),
    }),
  ),
  model: z.string(),
  usage: z.object({
    prompt_tokens: z.number(),
    total_tokens: z.number(),
  }),
});

const result = await ctx.integrations.mistral.apiRequest(
  {
    method: "POST",
    path: "/embeddings",
    body: {
      model: "mistral-embed",
      input: ["Hello world", "Bonjour le monde"],
    },
  },
  { response: EmbeddingsResponseSchema },
);

result.data.forEach((item, i) => {
  console.log(`Text ${i}: ${item.embedding.length} dimensions`);
});
```

### Function Calling

```typescript
const FunctionCallResponseSchema = z.object({
  id: z.string(),
  choices: z.array(
    z.object({
      message: z.object({
        role: z.string(),
        content: z.string().nullable(),
        tool_calls: z
          .array(
            z.object({
              id: z.string(),
              type: z.literal("function"),
              function: z.object({
                name: z.string(),
                arguments: z.string(),
              }),
            }),
          )
          .optional(),
      }),
      finish_reason: z.string(),
    }),
  ),
});

const result = await ctx.integrations.mistral.apiRequest(
  {
    method: "POST",
    path: "/chat/completions",
    body: {
      model: "mistral-large-latest",
      messages: [{ role: "user", content: "What's the weather in London?" }],
      tools: [
        {
          type: "function",
          function: {
            name: "get_weather",
            description: "Get weather for a location",
            parameters: {
              type: "object",
              properties: {
                location: { type: "string" },
                unit: { type: "string", enum: ["celsius", "fahrenheit"] },
              },
              required: ["location"],
            },
          },
        },
      ],
      tool_choice: "auto",
    },
  },
  { response: FunctionCallResponseSchema },
);
```

### JSON Mode

```typescript
const result = await ctx.integrations.mistral.apiRequest(
  {
    method: "POST",
    path: "/chat/completions",
    body: {
      model: "mistral-large-latest",
      messages: [
        {
          role: "user",
          content: "List 3 countries with capitals in JSON format",
        },
      ],
      response_format: { type: "json_object" },
    },
  },
  { response: ChatCompletionResponseSchema },
);

const data = JSON.parse(result.choices[0]?.message.content ?? "{}");
```

## Trace Metadata

All methods accept an optional `metadata` parameter as the last argument for diagnostics labeling. See the [root SDK README](../../../README.md#trace-metadata) for details.

## Common Pitfalls

### Streaming Is Not Supported

`apiRequest()` does not support streaming or Server-Sent Events. Do not set
`stream: true` — streaming responses fail schema validation. Every call
returns the complete response; if a UI needs real-time token streaming,
handle it at the frontend layer, not through the SDK.

### No Specialized Methods

```typescript
// WRONG - These methods do not exist
await mistral.chat({ ... });
await mistral.embed({ ... });

// CORRECT - Use apiRequest
await ctx.integrations.mistral.apiRequest(
  { method: "POST", path: "/chat/completions", body: { ... } },
  { response: ChatCompletionResponseSchema }
);
```

### Model Names Use "latest" Suffix

Mistral models typically use a `-latest` suffix for the current version:

```typescript
// Common model names
const models = [
  "mistral-large-latest",
  "mistral-medium-latest",
  "mistral-small-latest",
  "codestral-latest",
  "mistral-embed",
];
```

### Safe Mode

Mistral has a safe mode for content moderation:

```typescript
const result = await ctx.integrations.mistral.apiRequest(
  {
    method: "POST",
    path: "/chat/completions",
    body: {
      model: "mistral-large-latest",
      messages: [{ role: "user", content: "..." }],
      safe_prompt: true, // Enable safety guardrails
    },
  },
  { response: ChatCompletionResponseSchema },
);
```

### System Prompts

Mistral supports system messages:

```typescript
const result = await ctx.integrations.mistral.apiRequest(
  {
    method: "POST",
    path: "/chat/completions",
    body: {
      model: "mistral-large-latest",
      messages: [
        { role: "system", content: "You are a helpful coding assistant." },
        { role: "user", content: "Write a Python function..." },
      ],
    },
  },
  { response: ChatCompletionResponseSchema },
);
```

## Error Handling

```typescript
import { RestApiValidationError } from "@superblocksteam/sdk-api";

try {
  const result = await ctx.integrations.mistral.apiRequest(
    { method: "POST", path: "/chat/completions", body: { ... } },
    { response: ChatCompletionResponseSchema }
  );
} catch (error) {
  if (error instanceof RestApiValidationError) {
    console.error("Validation failed:", error.details.zodError);
  }
}
```

## API Reference

- [Mistral API Documentation](https://docs.mistral.ai/)
- [Chat Completions](https://docs.mistral.ai/api/#operation/createChatCompletion)
- [Embeddings](https://docs.mistral.ai/api/#operation/createEmbedding)
- [Models](https://docs.mistral.ai/getting-started/models/)
