File size: 1,758 Bytes
60faa09
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import OpenAI from "openai";

export async function callOpenAI({
  model, messages, temperature = 1.0, maxTokens = 2048,
  reasoning = false, stream = false, apiKey, onToken,
}) {
  const client = new OpenAI({ apiKey });
  const modelName = model.replace(/^openai:/, "");

  const openaiMessages = messages.map((m) => {
    if (m.imageUrl) {
      return {
        role: m.role,
        content: [
          { type: "text", text: m.content || "" },
          { type: "image_url", image_url: { url: m.imageUrl } },
        ],
      };
    }
    return { role: m.role, content: m.content };
  });

  const params = {
    model: modelName,
    messages: openaiMessages,
    temperature: reasoning ? undefined : Number(temperature),
    max_tokens: Number(maxTokens),
    stream,
  };

  if (reasoning || modelName.startsWith("o1") || modelName.startsWith("o3")) {
    delete params.temperature;
    delete params.max_tokens;
  }

  if (stream) {
    const completion = await client.chat.completions.create({
      ...params, stream: true, stream_options: { include_usage: true },
    });
    let fullText = "";
    let usage = null;
    for await (const chunk of completion) {
      const delta = chunk.choices?.[0]?.delta?.content;
      if (delta) { fullText += delta; onToken?.(delta); }
      if (chunk.usage) {
        usage = { promptTokens: chunk.usage.prompt_tokens, completionTokens: chunk.usage.completion_tokens };
      }
    }
    return { text: fullText, usage };
  }

  const completion = await client.chat.completions.create(params);
  return {
    text: completion.choices?.[0]?.message?.content || "",
    usage: {
      promptTokens: completion.usage?.prompt_tokens,
      completionTokens: completion.usage?.completion_tokens,
    },
  };
}