repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
public Clawd ADK gateway launch mirror
stars
latest
clone command
git clone gitlawb://did:key:z6Mkq5mY...iFZ5/my-project-publ...git clone gitlawb://did:key:z6Mkq5mY.../my-project-publ...2fa351d6docs: add automaton and perps launch sources16d ago| #1 | import { Mistral } from "@mistralai/mistralai"; |
| #2 | import { LLM, LLMResponse } from "./base"; |
| #3 | import { LLMConfig, Message } from "../types"; |
| #4 | |
| #5 | export class MistralLLM implements LLM { |
| #6 | private client: Mistral; |
| #7 | private model: string; |
| #8 | |
| #9 | constructor(config: LLMConfig) { |
| #10 | if (!config.apiKey) { |
| #11 | throw new Error("Mistral API key is required"); |
| #12 | } |
| #13 | this.client = new Mistral({ |
| #14 | apiKey: config.apiKey, |
| #15 | }); |
| #16 | this.model = config.model || "mistral-tiny-latest"; |
| #17 | } |
| #18 | |
| #19 | // Helper function to convert content to string |
| #20 | private contentToString(content: any): string { |
| #21 | if (typeof content === "string") { |
| #22 | return content; |
| #23 | } |
| #24 | if (Array.isArray(content)) { |
| #25 | // Handle ContentChunk array - extract text content |
| #26 | return content |
| #27 | .map((chunk) => { |
| #28 | if (chunk.type === "text") { |
| #29 | return chunk.text; |
| #30 | } else { |
| #31 | return JSON.stringify(chunk); |
| #32 | } |
| #33 | }) |
| #34 | .join(""); |
| #35 | } |
| #36 | return String(content || ""); |
| #37 | } |
| #38 | |
| #39 | async generateResponse( |
| #40 | messages: Message[], |
| #41 | responseFormat?: { type: string }, |
| #42 | tools?: any[], |
| #43 | ): Promise<string | LLMResponse> { |
| #44 | const response = await this.client.chat.complete({ |
| #45 | model: this.model, |
| #46 | messages: messages.map((msg) => ({ |
| #47 | role: msg.role as "system" | "user" | "assistant", |
| #48 | content: |
| #49 | typeof msg.content === "string" |
| #50 | ? msg.content |
| #51 | : JSON.stringify(msg.content), |
| #52 | })), |
| #53 | ...(tools && { tools }), |
| #54 | ...(responseFormat && { response_format: responseFormat }), |
| #55 | }); |
| #56 | |
| #57 | if (!response || !response.choices || response.choices.length === 0) { |
| #58 | return ""; |
| #59 | } |
| #60 | |
| #61 | const message = response.choices[0].message; |
| #62 | |
| #63 | if (!message) { |
| #64 | return ""; |
| #65 | } |
| #66 | |
| #67 | if (message.toolCalls && message.toolCalls.length > 0) { |
| #68 | return { |
| #69 | content: this.contentToString(message.content), |
| #70 | role: message.role || "assistant", |
| #71 | toolCalls: message.toolCalls.map((call) => ({ |
| #72 | name: call.function.name, |
| #73 | arguments: |
| #74 | typeof call.function.arguments === "string" |
| #75 | ? call.function.arguments |
| #76 | : JSON.stringify(call.function.arguments), |
| #77 | })), |
| #78 | }; |
| #79 | } |
| #80 | |
| #81 | return this.contentToString(message.content); |
| #82 | } |
| #83 | |
| #84 | async generateChat(messages: Message[]): Promise<LLMResponse> { |
| #85 | const formattedMessages = messages.map((msg) => ({ |
| #86 | role: msg.role as "system" | "user" | "assistant", |
| #87 | content: |
| #88 | typeof msg.content === "string" |
| #89 | ? msg.content |
| #90 | : JSON.stringify(msg.content), |
| #91 | })); |
| #92 | |
| #93 | const response = await this.client.chat.complete({ |
| #94 | model: this.model, |
| #95 | messages: formattedMessages, |
| #96 | }); |
| #97 | |
| #98 | if (!response || !response.choices || response.choices.length === 0) { |
| #99 | return { |
| #100 | content: "", |
| #101 | role: "assistant", |
| #102 | }; |
| #103 | } |
| #104 | |
| #105 | const message = response.choices[0].message; |
| #106 | |
| #107 | return { |
| #108 | content: this.contentToString(message.content), |
| #109 | role: message.role || "assistant", |
| #110 | }; |
| #111 | } |
| #112 | } |
| #113 |