@flink-app/mistral-adapter 2.0.0-alpha.103
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.
- package/LICENSE +21 -0
- package/README.md +163 -0
- package/dist/MistralAdapter.d.ts +158 -0
- package/dist/MistralAdapter.d.ts.map +1 -0
- package/dist/MistralAdapter.js +451 -0
- package/dist/MistralAdapter.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/package.json +48 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Frost Experience AB https://www.frost.se
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# @flink-app/mistral-adapter
|
|
2
|
+
|
|
3
|
+
Mistral AI adapter for the Flink AI framework. Provides integration with Mistral's models via the Chat Completions API using the official [`@mistralai/mistralai`](https://www.npmjs.com/package/@mistralai/mistralai) SDK.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @flink-app/mistral-adapter
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @flink-app/mistral-adapter
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The `@mistralai/mistralai` package is included as a dependency, so you don't need to install it separately.
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Basic Setup
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { MistralAdapter } from "@flink-app/mistral-adapter";
|
|
21
|
+
import { FlinkApp } from "@flink-app/flink";
|
|
22
|
+
|
|
23
|
+
const app = new FlinkApp({
|
|
24
|
+
ai: {
|
|
25
|
+
llms: {
|
|
26
|
+
default: new MistralAdapter({
|
|
27
|
+
apiKey: process.env.MISTRAL_API_KEY!,
|
|
28
|
+
model: "mistral-medium-latest"
|
|
29
|
+
}),
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
await app.start();
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Legacy API (still supported):**
|
|
38
|
+
```typescript
|
|
39
|
+
// Backward-compatible constructor
|
|
40
|
+
new MistralAdapter(process.env.MISTRAL_API_KEY!, "mistral-medium-latest")
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Agent Instructions
|
|
44
|
+
|
|
45
|
+
Define your agent's behavior using the `instructions` property:
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// src/agents/support_agent.ts
|
|
49
|
+
export const Agent: FlinkAgentProps = {
|
|
50
|
+
name: "support_agent",
|
|
51
|
+
instructions: "You are a helpful customer support agent.",
|
|
52
|
+
tools: ["get_order_status"],
|
|
53
|
+
model: { adapterId: "default" },
|
|
54
|
+
};
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**How it works:**
|
|
58
|
+
- Instructions are prepended as a system message to every conversation
|
|
59
|
+
- Follows Vercel AI SDK pattern for consistency
|
|
60
|
+
- Additional system messages in the conversation are passed through as-is
|
|
61
|
+
|
|
62
|
+
### Multiple Adapters
|
|
63
|
+
|
|
64
|
+
You can register multiple Mistral adapters with different configurations:
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
const app = new FlinkApp({
|
|
68
|
+
ai: {
|
|
69
|
+
llms: {
|
|
70
|
+
// Frontier model - best for agentic and coding use cases
|
|
71
|
+
default: new MistralAdapter({
|
|
72
|
+
apiKey: process.env.MISTRAL_API_KEY!,
|
|
73
|
+
model: "mistral-medium-latest"
|
|
74
|
+
}),
|
|
75
|
+
|
|
76
|
+
// Efficient model - good balance of capability and cost
|
|
77
|
+
fast: new MistralAdapter({
|
|
78
|
+
apiKey: process.env.MISTRAL_API_KEY!,
|
|
79
|
+
model: "mistral-small-latest"
|
|
80
|
+
}),
|
|
81
|
+
|
|
82
|
+
// Code completion specialist
|
|
83
|
+
code: new MistralAdapter({
|
|
84
|
+
apiKey: process.env.MISTRAL_API_KEY!,
|
|
85
|
+
model: "codestral-latest"
|
|
86
|
+
}),
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Debug Logging
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
const adapter = new MistralAdapter({
|
|
96
|
+
apiKey: process.env.MISTRAL_API_KEY!,
|
|
97
|
+
model: "mistral-medium-latest",
|
|
98
|
+
debug: true // Enable debug logging for this adapter
|
|
99
|
+
});
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
When `debug: true`, the adapter logs full request parameters and tool call decisions made by the LLM.
|
|
103
|
+
|
|
104
|
+
## Supported Models
|
|
105
|
+
|
|
106
|
+
This adapter works with all Mistral chat models. As of 2026:
|
|
107
|
+
|
|
108
|
+
| Use Case | Recommended Model | Why |
|
|
109
|
+
|----------|------------------|-----|
|
|
110
|
+
| General / agentic / coding | `mistral-medium-latest` | Mistral Medium 3.5 - frontier-class multimodal model optimized for agentic and coding use cases |
|
|
111
|
+
| Cost-efficient tasks | `mistral-small-latest` | Mistral Small 4 - hybrid model unifying instruct, reasoning, and coding |
|
|
112
|
+
| General-purpose (open weights) | `mistral-large-latest` | Mistral Large 3 - general-purpose multimodal model (Apache 2.0) |
|
|
113
|
+
| Code completion | `codestral-latest` | Codestral - code completion specialist |
|
|
114
|
+
| Edge / small footprint | Ministral 3 series (3B, 8B, 14B) | Compact text and vision models |
|
|
115
|
+
|
|
116
|
+
See the [Mistral models overview](https://docs.mistral.ai/models/overview) for the full, up-to-date list of model IDs.
|
|
117
|
+
|
|
118
|
+
## Features
|
|
119
|
+
|
|
120
|
+
- ✅ **Full tool calling support** - including parallel tool calls in a single response
|
|
121
|
+
- ✅ **Event-based streaming** - via the SDK's `chat.stream()`
|
|
122
|
+
- ✅ **Multimodal input** - text + image content blocks (https URLs and base64 data URLs)
|
|
123
|
+
- ✅ **Tool call ID normalization** - Mistral requires tool call IDs to be exactly 9 alphanumeric characters; IDs from conversation history that originated with another provider are deterministically remapped
|
|
124
|
+
- ✅ **Token usage tracking** - prompt and completion tokens reported per request
|
|
125
|
+
- ✅ **Schema sanitization** - tool input schemas cleaned for Mistral compatibility
|
|
126
|
+
|
|
127
|
+
## Architecture Notes
|
|
128
|
+
|
|
129
|
+
### Flink Integration
|
|
130
|
+
|
|
131
|
+
The adapter implements Flink's `LLMAdapter` interface:
|
|
132
|
+
|
|
133
|
+
- Flink's `instructions` → prepended as `{ role: "system" }` message
|
|
134
|
+
- Flink's `messages` → converted to Mistral chat messages (system/user/assistant/tool roles)
|
|
135
|
+
- Flink's tool schema → converted to Mistral's function format (`{ type: "function", function: {...} }`)
|
|
136
|
+
- Streamed deltas → mapped to Flink's `LLMStreamChunk` events (text, tool_call, usage, done)
|
|
137
|
+
|
|
138
|
+
**Each API call is one turn:**
|
|
139
|
+
- Flink's AgentRunner handles the multi-turn loop (call API → execute tools → call API again)
|
|
140
|
+
- Tool results are sent back as `{ role: "tool", toolCallId, content }` messages
|
|
141
|
+
|
|
142
|
+
### ESM-only SDK
|
|
143
|
+
|
|
144
|
+
The `@mistralai/mistralai` SDK v2 is ESM-only. This adapter is compiled to CommonJS (like the rest of the Flink ecosystem) and loads the SDK via a dynamic `import()`, so it works in both CommonJS and ESM applications without configuration.
|
|
145
|
+
|
|
146
|
+
### Temperature
|
|
147
|
+
|
|
148
|
+
Temperature is only sent to the API when the agent explicitly configured one — Mistral recommends values between 0.0 and 0.7, and the default varies by model.
|
|
149
|
+
|
|
150
|
+
## Requirements
|
|
151
|
+
|
|
152
|
+
- Node.js >= 18
|
|
153
|
+
- @flink-app/flink >= 2.0.0-alpha.102
|
|
154
|
+
|
|
155
|
+
## License
|
|
156
|
+
|
|
157
|
+
MIT
|
|
158
|
+
|
|
159
|
+
## Resources
|
|
160
|
+
|
|
161
|
+
- [Mistral AI documentation](https://docs.mistral.ai/)
|
|
162
|
+
- [Mistral models overview](https://docs.mistral.ai/models/overview)
|
|
163
|
+
- [Function calling guide](https://docs.mistral.ai/capabilities/function_calling/)
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import type { FlinkToolSchema, LLMAdapter, LLMMessage, LLMStreamChunk } from "@flink-app/flink/ai";
|
|
2
|
+
export interface MistralAdapterOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Mistral API key
|
|
5
|
+
*/
|
|
6
|
+
apiKey: string;
|
|
7
|
+
/**
|
|
8
|
+
* Model to use (e.g., "mistral-medium-latest", "mistral-small-latest", "mistral-large-latest")
|
|
9
|
+
*/
|
|
10
|
+
model: string;
|
|
11
|
+
/**
|
|
12
|
+
* Optional: Enable debug logging for development and troubleshooting
|
|
13
|
+
*
|
|
14
|
+
* When enabled, logs:
|
|
15
|
+
* - Full request parameters sent to Mistral
|
|
16
|
+
* - Tool call decisions made by the LLM
|
|
17
|
+
* - Token usage and performance metrics
|
|
18
|
+
*
|
|
19
|
+
* @default false
|
|
20
|
+
*/
|
|
21
|
+
debug?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Mistral AI adapter for Flink AI framework
|
|
25
|
+
*
|
|
26
|
+
* Provides integration with Mistral's models via the Chat Completions API
|
|
27
|
+
* using the official `@mistralai/mistralai` SDK.
|
|
28
|
+
* Supports tool calling, handles message formatting between Flink's standardized
|
|
29
|
+
* format and Mistral's API format, and provides streaming support.
|
|
30
|
+
*
|
|
31
|
+
* ## Architecture
|
|
32
|
+
*
|
|
33
|
+
* This adapter implements the LLMAdapter interface and handles:
|
|
34
|
+
* - Message conversion from Flink format to Mistral format (system/user/assistant/tool roles)
|
|
35
|
+
* - System instructions prepended as system message (Vercel AI SDK pattern)
|
|
36
|
+
* - Tool schema sanitization for Mistral compatibility
|
|
37
|
+
* - Streaming event processing via chat.stream()
|
|
38
|
+
* - Tool call ID normalization (Mistral requires exactly 9 alphanumeric characters)
|
|
39
|
+
*
|
|
40
|
+
* ## Basic Usage
|
|
41
|
+
* ```typescript
|
|
42
|
+
* import { MistralAdapter } from "@flink-app/mistral-adapter";
|
|
43
|
+
* import { FlinkApp } from "@flink-app/flink";
|
|
44
|
+
*
|
|
45
|
+
* const app = new FlinkApp({
|
|
46
|
+
* ai: {
|
|
47
|
+
* llms: {
|
|
48
|
+
* default: new MistralAdapter({
|
|
49
|
+
* apiKey: process.env.MISTRAL_API_KEY!,
|
|
50
|
+
* model: "mistral-medium-latest"
|
|
51
|
+
* }),
|
|
52
|
+
* },
|
|
53
|
+
* },
|
|
54
|
+
* });
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* ## Features
|
|
58
|
+
* - ✅ Full tool calling support (including parallel tool calls)
|
|
59
|
+
* - ✅ Streaming with event-based updates
|
|
60
|
+
* - ✅ Proper message conversion and system instruction handling
|
|
61
|
+
* - ✅ Schema sanitization for tool compatibility
|
|
62
|
+
* - ✅ Tool call ID normalization for cross-provider conversation history
|
|
63
|
+
* - ✅ Token usage tracking
|
|
64
|
+
* - ✅ Debug logging for tool calls
|
|
65
|
+
*/
|
|
66
|
+
export declare class MistralAdapter implements LLMAdapter<FlinkToolSchema> {
|
|
67
|
+
private apiKey;
|
|
68
|
+
private model;
|
|
69
|
+
debug: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Lazily created SDK client.
|
|
72
|
+
*
|
|
73
|
+
* The @mistralai/mistralai SDK is ESM-only, while Flink packages are compiled
|
|
74
|
+
* to CommonJS. A dynamic import() (preserved as-is by TypeScript under
|
|
75
|
+
* module "node16") is the reliable way to load it from CJS on all supported
|
|
76
|
+
* Node versions.
|
|
77
|
+
*/
|
|
78
|
+
private clientPromise?;
|
|
79
|
+
constructor(options: MistralAdapterOptions);
|
|
80
|
+
constructor(apiKey: string, model: string);
|
|
81
|
+
private getClient;
|
|
82
|
+
stream(params: {
|
|
83
|
+
instructions: string;
|
|
84
|
+
messages: LLMMessage[];
|
|
85
|
+
tools: FlinkToolSchema[];
|
|
86
|
+
maxTokens: number;
|
|
87
|
+
temperature?: number;
|
|
88
|
+
providerMetadata?: Record<string, any>;
|
|
89
|
+
}): AsyncGenerator<LLMStreamChunk>;
|
|
90
|
+
/**
|
|
91
|
+
* Convert Flink messages to Mistral Chat Completions format
|
|
92
|
+
*
|
|
93
|
+
* Mistral uses OpenAI-style chat messages:
|
|
94
|
+
* 1. System instructions as { role: "system" } messages
|
|
95
|
+
* 2. User messages with string content or content chunks (text + image_url)
|
|
96
|
+
* 3. Assistant messages with optional toolCalls array
|
|
97
|
+
* 4. Tool results as { role: "tool", toolCallId, content } messages
|
|
98
|
+
*/
|
|
99
|
+
private convertMessagesToMistralFormat;
|
|
100
|
+
/**
|
|
101
|
+
* Build Mistral user content from text/image content blocks.
|
|
102
|
+
* Returns a plain string when there are no images (most common case),
|
|
103
|
+
* or an array of text / image_url chunks for multimodal messages.
|
|
104
|
+
* Returns null if there are no user-facing blocks.
|
|
105
|
+
*/
|
|
106
|
+
private buildMistralUserContent;
|
|
107
|
+
/**
|
|
108
|
+
* Convert Flink tools to Mistral format
|
|
109
|
+
*
|
|
110
|
+
* Mistral uses the OpenAI Chat Completions externally-tagged format:
|
|
111
|
+
* { type: "function", function: { name, description, parameters: JSONSchema } }
|
|
112
|
+
*/
|
|
113
|
+
private convertToolsToMistralFormat;
|
|
114
|
+
/**
|
|
115
|
+
* Sanitize JSON Schema for Mistral's tool use
|
|
116
|
+
*
|
|
117
|
+
* Mistral is generally permissive with JSON Schema (OpenAI-compatible,
|
|
118
|
+
* no strict mode), so sanitization focuses on removing only problematic
|
|
119
|
+
* metadata:
|
|
120
|
+
* - $schema meta property (not part of the parameters contract)
|
|
121
|
+
*/
|
|
122
|
+
private sanitizeSchemaForMistral;
|
|
123
|
+
/**
|
|
124
|
+
* Stringify streamed tool call arguments
|
|
125
|
+
*
|
|
126
|
+
* The SDK types arguments as string | object — a complete object may arrive
|
|
127
|
+
* in one chunk, or a JSON string may be split across chunks.
|
|
128
|
+
*/
|
|
129
|
+
private stringifyArguments;
|
|
130
|
+
/**
|
|
131
|
+
* Normalize a tool call ID to Mistral's required format
|
|
132
|
+
*
|
|
133
|
+
* Mistral requires tool call IDs to be exactly 9 alphanumeric characters
|
|
134
|
+
* (a-z, A-Z, 0-9). IDs produced by this adapter already conform, but
|
|
135
|
+
* conversation history that originated from another provider (e.g.
|
|
136
|
+
* "call_abc123..." from OpenAI or "toolu_01..." from Anthropic) does not.
|
|
137
|
+
*
|
|
138
|
+
* Non-conforming IDs are mapped deterministically to a 9-character ID so
|
|
139
|
+
* that the assistant tool call and its matching tool result stay linked.
|
|
140
|
+
*/
|
|
141
|
+
private normalizeToolCallId;
|
|
142
|
+
/**
|
|
143
|
+
* Generate a valid Mistral tool call ID (9 alphanumeric characters)
|
|
144
|
+
* Used as fallback when the stream did not provide an ID
|
|
145
|
+
*/
|
|
146
|
+
private generateToolCallId;
|
|
147
|
+
/**
|
|
148
|
+
* Normalize Mistral finish reason to Flink format
|
|
149
|
+
*
|
|
150
|
+
* Maps Mistral's finishReason values:
|
|
151
|
+
* - "stop" → "end_turn"
|
|
152
|
+
* - "length" → "max_tokens"
|
|
153
|
+
* - "tool_calls" → "tool_use"
|
|
154
|
+
* - "error" / others → "end_turn"
|
|
155
|
+
*/
|
|
156
|
+
private normalizeStopReason;
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=MistralAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MistralAdapter.d.ts","sourceRoot":"","sources":["../src/MistralAdapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAmB,UAAU,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAcpH,MAAM,WAAW,qBAAqB;IAClC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;;;;;;;OASG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,qBAAa,cAAe,YAAW,UAAU,CAAC,eAAe,CAAC;IAC9D,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;IACf,KAAK,EAAE,OAAO,CAAC;IAEtB;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa,CAAC,CAAmB;gBAE7B,OAAO,EAAE,qBAAqB;gBAC9B,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAezC,OAAO,CAAC,SAAS;IAOV,MAAM,CAAC,MAAM,EAAE;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,UAAU,EAAE,CAAC;QACvB,KAAK,EAAE,eAAe,EAAE,CAAC;QACzB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KAC1C,GAAG,cAAc,CAAC,cAAc,CAAC;IA6IlC;;;;;;;;OAQG;IACH,OAAO,CAAC,8BAA8B;IAmGtC;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;IAsB/B;;;;;OAKG;IACH,OAAO,CAAC,2BAA2B;IAWnC;;;;;;;OAOG;IACH,OAAO,CAAC,wBAAwB;IAyChC;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAM1B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,mBAAmB;IAqB3B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAS1B;;;;;;;;OAQG;IACH,OAAO,CAAC,mBAAmB;CAW9B"}
|
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MistralAdapter = void 0;
|
|
4
|
+
const flink_1 = require("@flink-app/flink");
|
|
5
|
+
/**
|
|
6
|
+
* Mistral AI adapter for Flink AI framework
|
|
7
|
+
*
|
|
8
|
+
* Provides integration with Mistral's models via the Chat Completions API
|
|
9
|
+
* using the official `@mistralai/mistralai` SDK.
|
|
10
|
+
* Supports tool calling, handles message formatting between Flink's standardized
|
|
11
|
+
* format and Mistral's API format, and provides streaming support.
|
|
12
|
+
*
|
|
13
|
+
* ## Architecture
|
|
14
|
+
*
|
|
15
|
+
* This adapter implements the LLMAdapter interface and handles:
|
|
16
|
+
* - Message conversion from Flink format to Mistral format (system/user/assistant/tool roles)
|
|
17
|
+
* - System instructions prepended as system message (Vercel AI SDK pattern)
|
|
18
|
+
* - Tool schema sanitization for Mistral compatibility
|
|
19
|
+
* - Streaming event processing via chat.stream()
|
|
20
|
+
* - Tool call ID normalization (Mistral requires exactly 9 alphanumeric characters)
|
|
21
|
+
*
|
|
22
|
+
* ## Basic Usage
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { MistralAdapter } from "@flink-app/mistral-adapter";
|
|
25
|
+
* import { FlinkApp } from "@flink-app/flink";
|
|
26
|
+
*
|
|
27
|
+
* const app = new FlinkApp({
|
|
28
|
+
* ai: {
|
|
29
|
+
* llms: {
|
|
30
|
+
* default: new MistralAdapter({
|
|
31
|
+
* apiKey: process.env.MISTRAL_API_KEY!,
|
|
32
|
+
* model: "mistral-medium-latest"
|
|
33
|
+
* }),
|
|
34
|
+
* },
|
|
35
|
+
* },
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* ## Features
|
|
40
|
+
* - ✅ Full tool calling support (including parallel tool calls)
|
|
41
|
+
* - ✅ Streaming with event-based updates
|
|
42
|
+
* - ✅ Proper message conversion and system instruction handling
|
|
43
|
+
* - ✅ Schema sanitization for tool compatibility
|
|
44
|
+
* - ✅ Tool call ID normalization for cross-provider conversation history
|
|
45
|
+
* - ✅ Token usage tracking
|
|
46
|
+
* - ✅ Debug logging for tool calls
|
|
47
|
+
*/
|
|
48
|
+
class MistralAdapter {
|
|
49
|
+
constructor(optionsOrApiKey, model) {
|
|
50
|
+
if (typeof optionsOrApiKey === "string") {
|
|
51
|
+
// Legacy constructor: new MistralAdapter(apiKey, model)
|
|
52
|
+
this.apiKey = optionsOrApiKey;
|
|
53
|
+
this.model = model;
|
|
54
|
+
this.debug = false; // Default: no debug logging
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
// New constructor: new MistralAdapter({ apiKey, model, debug })
|
|
58
|
+
this.apiKey = optionsOrApiKey.apiKey;
|
|
59
|
+
this.model = optionsOrApiKey.model;
|
|
60
|
+
this.debug = optionsOrApiKey.debug ?? false; // Default: no debug logging
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
getClient() {
|
|
64
|
+
if (!this.clientPromise) {
|
|
65
|
+
this.clientPromise = import("@mistralai/mistralai").then(({ Mistral }) => new Mistral({ apiKey: this.apiKey }));
|
|
66
|
+
}
|
|
67
|
+
return this.clientPromise;
|
|
68
|
+
}
|
|
69
|
+
async *stream(params) {
|
|
70
|
+
try {
|
|
71
|
+
const client = await this.getClient();
|
|
72
|
+
const messages = this.convertMessagesToMistralFormat(params.instructions, params.messages);
|
|
73
|
+
const tools = params.tools.length > 0 ? this.convertToolsToMistralFormat(params.tools) : undefined;
|
|
74
|
+
const streamParams = {
|
|
75
|
+
model: this.model,
|
|
76
|
+
messages: messages,
|
|
77
|
+
tools: tools,
|
|
78
|
+
maxTokens: params.maxTokens,
|
|
79
|
+
// Only sent when the agent explicitly configured a temperature
|
|
80
|
+
...(params.temperature !== undefined ? { temperature: params.temperature } : {}),
|
|
81
|
+
};
|
|
82
|
+
if (this.debug) {
|
|
83
|
+
flink_1.log.debug(`[Mistral Stream] Starting stream request:`, JSON.stringify(streamParams, null, 2));
|
|
84
|
+
}
|
|
85
|
+
const stream = await client.chat.stream(streamParams);
|
|
86
|
+
let inputTokens = 0;
|
|
87
|
+
let outputTokens = 0;
|
|
88
|
+
let finishReason = "stop";
|
|
89
|
+
// Track in-progress tool calls — arguments may arrive incrementally across chunks
|
|
90
|
+
const pendingToolCalls = new Map();
|
|
91
|
+
for await (const event of stream) {
|
|
92
|
+
const chunk = event.data;
|
|
93
|
+
// Usage arrives on the final chunk
|
|
94
|
+
if (chunk.usage) {
|
|
95
|
+
inputTokens = chunk.usage.promptTokens ?? 0;
|
|
96
|
+
outputTokens = chunk.usage.completionTokens ?? 0;
|
|
97
|
+
}
|
|
98
|
+
const choice = chunk.choices?.[0];
|
|
99
|
+
if (!choice)
|
|
100
|
+
continue;
|
|
101
|
+
const delta = choice.delta;
|
|
102
|
+
// Text content — plain string or content chunks
|
|
103
|
+
if (typeof delta.content === "string" && delta.content) {
|
|
104
|
+
yield { type: "text", delta: delta.content };
|
|
105
|
+
}
|
|
106
|
+
else if (Array.isArray(delta.content)) {
|
|
107
|
+
for (const contentChunk of delta.content) {
|
|
108
|
+
if (contentChunk.type === "text" && contentChunk.text) {
|
|
109
|
+
yield { type: "text", delta: contentChunk.text };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Tool calls — accumulate by index (arguments may be split across chunks)
|
|
114
|
+
if (delta.toolCalls) {
|
|
115
|
+
for (const toolCall of delta.toolCalls) {
|
|
116
|
+
const index = toolCall.index ?? 0;
|
|
117
|
+
const existing = pendingToolCalls.get(index);
|
|
118
|
+
if (existing) {
|
|
119
|
+
if (toolCall.id)
|
|
120
|
+
existing.id = toolCall.id;
|
|
121
|
+
if (toolCall.function?.name)
|
|
122
|
+
existing.name = toolCall.function.name;
|
|
123
|
+
existing.argumentsJson += this.stringifyArguments(toolCall.function?.arguments);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
pendingToolCalls.set(index, {
|
|
127
|
+
id: toolCall.id || this.generateToolCallId(),
|
|
128
|
+
name: toolCall.function?.name || "",
|
|
129
|
+
argumentsJson: this.stringifyArguments(toolCall.function?.arguments),
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (choice.finishReason) {
|
|
135
|
+
finishReason = choice.finishReason;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Yield completed tool calls after stream finishes (index order = call order)
|
|
139
|
+
const completedToolCalls = [...pendingToolCalls.entries()].sort(([a], [b]) => a - b);
|
|
140
|
+
for (const [, toolCall] of completedToolCalls) {
|
|
141
|
+
const input = toolCall.argumentsJson ? JSON.parse(toolCall.argumentsJson) : {};
|
|
142
|
+
if (this.debug) {
|
|
143
|
+
flink_1.log.debug(`[Mistral Stream] LLM decided to call tool:`, JSON.stringify({ name: toolCall.name, id: toolCall.id, input }, null, 2));
|
|
144
|
+
}
|
|
145
|
+
yield {
|
|
146
|
+
type: "tool_call",
|
|
147
|
+
toolCall: {
|
|
148
|
+
id: toolCall.id,
|
|
149
|
+
name: toolCall.name,
|
|
150
|
+
input,
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
yield {
|
|
155
|
+
type: "usage",
|
|
156
|
+
usage: {
|
|
157
|
+
inputTokens,
|
|
158
|
+
outputTokens,
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
yield {
|
|
162
|
+
type: "done",
|
|
163
|
+
stopReason: this.normalizeStopReason(finishReason),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
const status = error?.statusCode ?? error?.status;
|
|
168
|
+
if (status === 400) {
|
|
169
|
+
throw new Error(`Mistral API error (400 Bad Request): ${error.message || "Invalid request"}. ` +
|
|
170
|
+
`Common causes: invalid model name, malformed messages, or invalid tool schemas. ` +
|
|
171
|
+
`Model: ${this.model}`);
|
|
172
|
+
}
|
|
173
|
+
else if (status === 401 || status === 403) {
|
|
174
|
+
throw new Error(`Mistral API authentication error (${status}): Invalid API key or insufficient permissions. ` +
|
|
175
|
+
`Verify your MISTRAL_API_KEY environment variable is set correctly.`);
|
|
176
|
+
}
|
|
177
|
+
else if (status === 429) {
|
|
178
|
+
throw new Error(`Mistral API rate limit exceeded (429 Too Many Requests): ${error.message || "Rate limit hit"}. ` +
|
|
179
|
+
`Consider implementing retry logic with exponential backoff or upgrading your quota.`);
|
|
180
|
+
}
|
|
181
|
+
else if (status === 500 || status === 503) {
|
|
182
|
+
throw new Error(`Mistral API server error (${status}): ${error.message || "Internal server error"}. ` +
|
|
183
|
+
`This is a temporary issue with Mistral's servers. Please retry your request.`);
|
|
184
|
+
}
|
|
185
|
+
throw error;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Convert Flink messages to Mistral Chat Completions format
|
|
190
|
+
*
|
|
191
|
+
* Mistral uses OpenAI-style chat messages:
|
|
192
|
+
* 1. System instructions as { role: "system" } messages
|
|
193
|
+
* 2. User messages with string content or content chunks (text + image_url)
|
|
194
|
+
* 3. Assistant messages with optional toolCalls array
|
|
195
|
+
* 4. Tool results as { role: "tool", toolCallId, content } messages
|
|
196
|
+
*/
|
|
197
|
+
convertMessagesToMistralFormat(instructions, messages) {
|
|
198
|
+
const result = [];
|
|
199
|
+
// 1. Prepend instructions as system message (Vercel AI SDK pattern)
|
|
200
|
+
if (instructions) {
|
|
201
|
+
result.push({
|
|
202
|
+
role: "system",
|
|
203
|
+
content: instructions,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
for (const msg of messages) {
|
|
207
|
+
// 2. Handle additional system messages (for dynamic context)
|
|
208
|
+
if (msg.role === "system") {
|
|
209
|
+
result.push({
|
|
210
|
+
role: "system",
|
|
211
|
+
content: msg.content,
|
|
212
|
+
});
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
// 3. Handle user messages
|
|
216
|
+
if (msg.role === "user") {
|
|
217
|
+
if (typeof msg.content === "string") {
|
|
218
|
+
result.push({
|
|
219
|
+
role: "user",
|
|
220
|
+
content: msg.content,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
const content = msg.content;
|
|
225
|
+
const toolResultBlocks = content.filter((block) => block.type === "tool_result");
|
|
226
|
+
const userBlocks = content.filter((block) => block.type !== "tool_result");
|
|
227
|
+
// Tool results become dedicated tool role messages
|
|
228
|
+
for (const block of toolResultBlocks) {
|
|
229
|
+
if (block.type === "tool_result") {
|
|
230
|
+
result.push({
|
|
231
|
+
role: "tool",
|
|
232
|
+
toolCallId: this.normalizeToolCallId(block.tool_use_id),
|
|
233
|
+
content: block.content,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
// Remaining user content (text + images)
|
|
238
|
+
const userContent = this.buildMistralUserContent(userBlocks);
|
|
239
|
+
if (userContent) {
|
|
240
|
+
result.push({ role: "user", content: userContent });
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
// 4. Handle assistant messages
|
|
246
|
+
if (msg.role === "assistant") {
|
|
247
|
+
if (typeof msg.content === "string") {
|
|
248
|
+
result.push({
|
|
249
|
+
role: "assistant",
|
|
250
|
+
content: msg.content,
|
|
251
|
+
});
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
const content = msg.content;
|
|
255
|
+
const textBlocks = content.filter((block) => block.type === "text");
|
|
256
|
+
const toolUseBlocks = content.filter((block) => block.type === "tool_use");
|
|
257
|
+
const text = textBlocks
|
|
258
|
+
.map((block) => (block.type === "text" ? block.text : ""))
|
|
259
|
+
.join("");
|
|
260
|
+
const toolCalls = [];
|
|
261
|
+
for (const block of toolUseBlocks) {
|
|
262
|
+
if (block.type === "tool_use") {
|
|
263
|
+
toolCalls.push({
|
|
264
|
+
id: this.normalizeToolCallId(block.id),
|
|
265
|
+
type: "function",
|
|
266
|
+
function: {
|
|
267
|
+
name: block.name,
|
|
268
|
+
arguments: JSON.stringify(block.input),
|
|
269
|
+
},
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (text || toolCalls.length > 0) {
|
|
274
|
+
result.push({
|
|
275
|
+
role: "assistant",
|
|
276
|
+
content: text || null,
|
|
277
|
+
...(toolCalls.length > 0 ? { toolCalls } : {}),
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return result;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Build Mistral user content from text/image content blocks.
|
|
287
|
+
* Returns a plain string when there are no images (most common case),
|
|
288
|
+
* or an array of text / image_url chunks for multimodal messages.
|
|
289
|
+
* Returns null if there are no user-facing blocks.
|
|
290
|
+
*/
|
|
291
|
+
buildMistralUserContent(blocks) {
|
|
292
|
+
const textBlocks = blocks.filter((b) => b.type === "text");
|
|
293
|
+
const imageBlocks = blocks.filter((b) => b.type === "image");
|
|
294
|
+
if (imageBlocks.length === 0) {
|
|
295
|
+
// Text-only: keep as plain string
|
|
296
|
+
const text = textBlocks.map((b) => (b.type === "text" ? b.text : "")).join("");
|
|
297
|
+
return text || null;
|
|
298
|
+
}
|
|
299
|
+
// Multimodal: build content chunk array
|
|
300
|
+
const content = [];
|
|
301
|
+
for (const block of textBlocks) {
|
|
302
|
+
if (block.type === "text")
|
|
303
|
+
content.push({ type: "text", text: block.text });
|
|
304
|
+
}
|
|
305
|
+
for (const block of imageBlocks) {
|
|
306
|
+
// Mistral accepts both https URLs and base64 data URLs directly
|
|
307
|
+
if (block.type === "image")
|
|
308
|
+
content.push({ type: "image_url", imageUrl: block.url });
|
|
309
|
+
}
|
|
310
|
+
return content.length > 0 ? content : null;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Convert Flink tools to Mistral format
|
|
314
|
+
*
|
|
315
|
+
* Mistral uses the OpenAI Chat Completions externally-tagged format:
|
|
316
|
+
* { type: "function", function: { name, description, parameters: JSONSchema } }
|
|
317
|
+
*/
|
|
318
|
+
convertToolsToMistralFormat(tools) {
|
|
319
|
+
return tools.map((tool) => ({
|
|
320
|
+
type: "function",
|
|
321
|
+
function: {
|
|
322
|
+
name: tool.name,
|
|
323
|
+
description: tool.description,
|
|
324
|
+
parameters: this.sanitizeSchemaForMistral(tool.inputSchema),
|
|
325
|
+
},
|
|
326
|
+
}));
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Sanitize JSON Schema for Mistral's tool use
|
|
330
|
+
*
|
|
331
|
+
* Mistral is generally permissive with JSON Schema (OpenAI-compatible,
|
|
332
|
+
* no strict mode), so sanitization focuses on removing only problematic
|
|
333
|
+
* metadata:
|
|
334
|
+
* - $schema meta property (not part of the parameters contract)
|
|
335
|
+
*/
|
|
336
|
+
sanitizeSchemaForMistral(schema) {
|
|
337
|
+
// Deep clone to avoid mutating the original schema
|
|
338
|
+
const sanitized = JSON.parse(JSON.stringify(schema));
|
|
339
|
+
const sanitizeNode = (node) => {
|
|
340
|
+
if (!node || typeof node !== "object")
|
|
341
|
+
return;
|
|
342
|
+
// Remove $schema meta property if present
|
|
343
|
+
delete node.$schema;
|
|
344
|
+
// Recursively sanitize nested structures
|
|
345
|
+
if (node.properties) {
|
|
346
|
+
for (const key in node.properties) {
|
|
347
|
+
sanitizeNode(node.properties[key]);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
if (node.items) {
|
|
351
|
+
if (Array.isArray(node.items)) {
|
|
352
|
+
node.items.forEach(sanitizeNode);
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
sanitizeNode(node.items);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
if (node.allOf)
|
|
359
|
+
node.allOf.forEach(sanitizeNode);
|
|
360
|
+
if (node.anyOf)
|
|
361
|
+
node.anyOf.forEach(sanitizeNode);
|
|
362
|
+
if (node.oneOf)
|
|
363
|
+
node.oneOf.forEach(sanitizeNode);
|
|
364
|
+
if (node.not)
|
|
365
|
+
sanitizeNode(node.not);
|
|
366
|
+
if (node.$defs && typeof node.$defs === "object") {
|
|
367
|
+
for (const def of Object.values(node.$defs)) {
|
|
368
|
+
sanitizeNode(def);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
sanitizeNode(sanitized);
|
|
373
|
+
return sanitized;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Stringify streamed tool call arguments
|
|
377
|
+
*
|
|
378
|
+
* The SDK types arguments as string | object — a complete object may arrive
|
|
379
|
+
* in one chunk, or a JSON string may be split across chunks.
|
|
380
|
+
*/
|
|
381
|
+
stringifyArguments(args) {
|
|
382
|
+
if (typeof args === "string")
|
|
383
|
+
return args;
|
|
384
|
+
if (args && typeof args === "object")
|
|
385
|
+
return JSON.stringify(args);
|
|
386
|
+
return "";
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Normalize a tool call ID to Mistral's required format
|
|
390
|
+
*
|
|
391
|
+
* Mistral requires tool call IDs to be exactly 9 alphanumeric characters
|
|
392
|
+
* (a-z, A-Z, 0-9). IDs produced by this adapter already conform, but
|
|
393
|
+
* conversation history that originated from another provider (e.g.
|
|
394
|
+
* "call_abc123..." from OpenAI or "toolu_01..." from Anthropic) does not.
|
|
395
|
+
*
|
|
396
|
+
* Non-conforming IDs are mapped deterministically to a 9-character ID so
|
|
397
|
+
* that the assistant tool call and its matching tool result stay linked.
|
|
398
|
+
*/
|
|
399
|
+
normalizeToolCallId(id) {
|
|
400
|
+
if (/^[a-zA-Z0-9]{9}$/.test(id))
|
|
401
|
+
return id;
|
|
402
|
+
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
403
|
+
// FNV-1a hash seeds a simple LCG that emits 9 base-62 characters
|
|
404
|
+
let hash = 0x811c9dc5;
|
|
405
|
+
for (let i = 0; i < id.length; i++) {
|
|
406
|
+
hash ^= id.charCodeAt(i);
|
|
407
|
+
hash = Math.imul(hash, 0x01000193) >>> 0;
|
|
408
|
+
}
|
|
409
|
+
let result = "";
|
|
410
|
+
let state = hash >>> 0;
|
|
411
|
+
for (let i = 0; i < 9; i++) {
|
|
412
|
+
state = (Math.imul(state, 1664525) + 1013904223) >>> 0;
|
|
413
|
+
result += chars[state % 62];
|
|
414
|
+
}
|
|
415
|
+
return result;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Generate a valid Mistral tool call ID (9 alphanumeric characters)
|
|
419
|
+
* Used as fallback when the stream did not provide an ID
|
|
420
|
+
*/
|
|
421
|
+
generateToolCallId() {
|
|
422
|
+
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
423
|
+
let result = "";
|
|
424
|
+
for (let i = 0; i < 9; i++) {
|
|
425
|
+
result += chars[Math.floor(Math.random() * chars.length)];
|
|
426
|
+
}
|
|
427
|
+
return result;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Normalize Mistral finish reason to Flink format
|
|
431
|
+
*
|
|
432
|
+
* Maps Mistral's finishReason values:
|
|
433
|
+
* - "stop" → "end_turn"
|
|
434
|
+
* - "length" → "max_tokens"
|
|
435
|
+
* - "tool_calls" → "tool_use"
|
|
436
|
+
* - "error" / others → "end_turn"
|
|
437
|
+
*/
|
|
438
|
+
normalizeStopReason(finishReason) {
|
|
439
|
+
switch (finishReason) {
|
|
440
|
+
case "tool_calls":
|
|
441
|
+
return "tool_use";
|
|
442
|
+
case "length":
|
|
443
|
+
return "max_tokens";
|
|
444
|
+
case "stop":
|
|
445
|
+
default:
|
|
446
|
+
return "end_turn";
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
exports.MistralAdapter = MistralAdapter;
|
|
451
|
+
//# sourceMappingURL=MistralAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MistralAdapter.js","sourceRoot":"","sources":["../src/MistralAdapter.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MistralAdapter = void 0;
|
|
4
|
+
var MistralAdapter_1 = require("./MistralAdapter");
|
|
5
|
+
Object.defineProperty(exports, "MistralAdapter", { enumerable: true, get: function () { return MistralAdapter_1.MistralAdapter; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mDAA8E;AAArE,gHAAA,cAAc,OAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flink-app/mistral-adapter",
|
|
3
|
+
"version": "2.0.0-alpha.103",
|
|
4
|
+
"description": "Mistral AI adapter for Flink AI framework",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"flink",
|
|
9
|
+
"mistral",
|
|
10
|
+
"ai",
|
|
11
|
+
"llm",
|
|
12
|
+
"adapter"
|
|
13
|
+
],
|
|
14
|
+
"author": "Frost Digital",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@mistralai/mistralai": "^2.5.0"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"@flink-app/flink": ">=2.0.0-alpha.103"
|
|
21
|
+
},
|
|
22
|
+
"peerDependenciesMeta": {
|
|
23
|
+
"@flink-app/flink": {
|
|
24
|
+
"optional": false
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/jasmine": "^3.7.1",
|
|
29
|
+
"ts-node": "^10.9.2",
|
|
30
|
+
"typescript": "^5.6.2",
|
|
31
|
+
"@flink-app/flink": "2.0.0-alpha.103"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist",
|
|
35
|
+
"README.md"
|
|
36
|
+
],
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "https://github.com/FrostDigital/flink-framework.git",
|
|
40
|
+
"directory": "packages/mistral-adapter"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsc --project tsconfig.dist.json",
|
|
44
|
+
"watch": "tsc --project tsconfig.dist.json --watch",
|
|
45
|
+
"test": "../../node_modules/.bin/jasmine-ts --config=./spec/support/jasmine.json",
|
|
46
|
+
"clean": "rm -rf dist"
|
|
47
|
+
}
|
|
48
|
+
}
|