MCPcopy Create free account
hub / github.com/Zoo-Code-Org/Zoo-Code / createMessage

Method createMessage

src/api/providers/openai.ts:80–274  ·  view source on GitHub ↗
(
		systemPrompt: string,
		messages: Anthropic.Messages.MessageParam[],
		metadata?: ApiHandlerCreateMessageMetadata,
	)

Source from the content-addressed store, hash-verified

78 }
79
80 override async *createMessage(
81 systemPrompt: string,
82 messages: Anthropic.Messages.MessageParam[],
83 metadata?: ApiHandlerCreateMessageMetadata,
84 ): ApiStream {
85 const { info: modelInfo, reasoning } = this.getModel()
86 const modelUrl = this.options.openAiBaseUrl ?? ""
87 const modelId = this.options.openAiModelId ?? ""
88 const enabledR1Format = this.options.openAiR1FormatEnabled ?? false
89 const isAzureAiInference = this._isAzureAiInference(modelUrl)
90 const deepseekReasoner = modelId.includes("deepseek-reasoner") || enabledR1Format
91
92 if (modelId.includes("o1") || modelId.includes("o3") || modelId.includes("o4")) {
93 yield* this.handleO3FamilyMessage(modelId, systemPrompt, messages, metadata)
94 return
95 }
96
97 let systemMessage: OpenAI.Chat.ChatCompletionSystemMessageParam = {
98 role: "system",
99 content: systemPrompt,
100 }
101
102 if (this.options.openAiStreamingEnabled ?? true) {
103 let convertedMessages
104
105 if (deepseekReasoner) {
106 convertedMessages = convertToR1Format([{ role: "user", content: systemPrompt }, ...messages])
107 } else {
108 if (modelInfo.supportsPromptCache) {
109 systemMessage = {
110 role: "system",
111 content: [
112 {
113 type: "text",
114 text: systemPrompt,
115 // @ts-ignore-next-line
116 cache_control: { type: "ephemeral" },
117 },
118 ],
119 }
120 }
121
122 convertedMessages = [systemMessage, ...convertToOpenAiMessages(messages)]
123
124 if (modelInfo.supportsPromptCache) {
125 // Note: the following logic is copied from openrouter:
126 // Add cache_control to the last two user messages
127 // (note: this works because we only ever add one user message at a time, but if we added multiple we'd need to mark the user message before the last assistant message)
128 const lastTwoUserMessages = convertedMessages.filter((msg) => msg.role === "user").slice(-2)
129
130 lastTwoUserMessages.forEach((msg) => {
131 if (typeof msg.content === "string") {
132 msg.content = [{ type: "text", text: msg.content }]
133 }
134
135 if (Array.isArray(msg.content)) {
136 // NOTE: this is fine since env details will always be added at the end. but if it weren't there, and the user added a image_url type message, it would pop a text part before it and then move it after to the end.
137 let lastTextPart = msg.content.filter((part) => part.type === "text").pop()

Callers

nothing calls this directly

Calls 15

getModelMethod · 0.95
_isAzureAiInferenceMethod · 0.95
handleO3FamilyMessageMethod · 0.95
_isGrokXAIMethod · 0.95
addMaxTokensIfNeededMethod · 0.95
updateMethod · 0.95
processToolCallsMethod · 0.95
finalMethod · 0.95
processUsageMetricsMethod · 0.95
convertToR1FormatFunction · 0.90
convertToOpenAiMessagesFunction · 0.90
handleOpenAIErrorFunction · 0.90

Tested by

no test coverage detected