@ainetwork/adk-provider-model-azure 0.8.1 → 0.8.2
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/dist/index.cjs +134 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +134 -40
- package/dist/index.js.map +1 -1
- package/index.ts +156 -45
- package/package.json +3 -3
- package/tests/fetch-behavior.test.ts +265 -0
- package/tsup.config.ts +7 -7
package/dist/index.cjs
CHANGED
|
@@ -25,7 +25,11 @@ __export(index_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(index_exports);
|
|
26
26
|
var import_modules = require("@ainetwork/adk/modules");
|
|
27
27
|
var import_memory = require("@ainetwork/adk/types/memory");
|
|
28
|
+
var import_logger = require("@ainetwork/adk/utils/logger");
|
|
28
29
|
var import_openai = require("openai");
|
|
30
|
+
var DEFAULT_TIMEOUT_MS = 12e4;
|
|
31
|
+
var DEFAULT_MAX_RETRIES = 1;
|
|
32
|
+
var PROVIDER = "azure-openai";
|
|
29
33
|
var AzureOpenAI = class extends import_modules.BaseModel {
|
|
30
34
|
client;
|
|
31
35
|
modelName;
|
|
@@ -35,7 +39,9 @@ var AzureOpenAI = class extends import_modules.BaseModel {
|
|
|
35
39
|
baseUrl,
|
|
36
40
|
apiKey,
|
|
37
41
|
apiVersion,
|
|
38
|
-
modelName
|
|
42
|
+
modelName,
|
|
43
|
+
timeout = DEFAULT_TIMEOUT_MS,
|
|
44
|
+
maxRetries = DEFAULT_MAX_RETRIES
|
|
39
45
|
}) {
|
|
40
46
|
super();
|
|
41
47
|
const options = {
|
|
@@ -43,7 +49,9 @@ var AzureOpenAI = class extends import_modules.BaseModel {
|
|
|
43
49
|
apiKey,
|
|
44
50
|
deployment,
|
|
45
51
|
apiVersion,
|
|
46
|
-
baseURL: baseUrl
|
|
52
|
+
baseURL: baseUrl,
|
|
53
|
+
timeout,
|
|
54
|
+
maxRetries
|
|
47
55
|
};
|
|
48
56
|
this.client = new import_openai.AzureOpenAI(options);
|
|
49
57
|
this.modelName = modelName;
|
|
@@ -53,12 +61,36 @@ var AzureOpenAI = class extends import_modules.BaseModel {
|
|
|
53
61
|
case import_memory.MessageRole.USER:
|
|
54
62
|
return "user";
|
|
55
63
|
case import_memory.MessageRole.MODEL:
|
|
64
|
+
return "assistant";
|
|
56
65
|
case import_memory.MessageRole.SYSTEM:
|
|
57
66
|
return "system";
|
|
58
67
|
default:
|
|
59
68
|
return "system";
|
|
60
69
|
}
|
|
61
70
|
}
|
|
71
|
+
logCallStart(method, messageCount, toolCount = 0) {
|
|
72
|
+
import_logger.loggers.model.debug(`[${PROVIDER}] ${method} start`, {
|
|
73
|
+
provider: PROVIDER,
|
|
74
|
+
model: this.modelName,
|
|
75
|
+
messageCount,
|
|
76
|
+
toolCount
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
logCallSuccess(method, startedAt) {
|
|
80
|
+
import_logger.loggers.model.info(`[${PROVIDER}] ${method} complete`, {
|
|
81
|
+
provider: PROVIDER,
|
|
82
|
+
model: this.modelName,
|
|
83
|
+
durationMs: Date.now() - startedAt
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
logCallFailure(method, startedAt, error) {
|
|
87
|
+
import_logger.loggers.model.error(`[${PROVIDER}] ${method} failed`, {
|
|
88
|
+
provider: PROVIDER,
|
|
89
|
+
model: this.modelName,
|
|
90
|
+
durationMs: Date.now() - startedAt,
|
|
91
|
+
error: error instanceof Error ? error.message : String(error)
|
|
92
|
+
});
|
|
93
|
+
}
|
|
62
94
|
generateMessages(params) {
|
|
63
95
|
const { query, thread, systemPrompt } = params;
|
|
64
96
|
const messages = !systemPrompt ? [] : [{ role: "system", content: systemPrompt.trim() }];
|
|
@@ -96,55 +128,117 @@ var AzureOpenAI = class extends import_modules.BaseModel {
|
|
|
96
128
|
});
|
|
97
129
|
}
|
|
98
130
|
async fetch(messages, options) {
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
reasoning_effort: options?.reasoning,
|
|
103
|
-
verbosity: options?.verbosity
|
|
104
|
-
});
|
|
105
|
-
return {
|
|
106
|
-
content: response.choices[0].message.content || void 0
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
async fetchWithContextMessage(messages, functions, options) {
|
|
110
|
-
if (functions.length > 0) {
|
|
131
|
+
const startedAt = Date.now();
|
|
132
|
+
this.logCallStart("fetch", messages.length);
|
|
133
|
+
try {
|
|
111
134
|
const response = await this.client.chat.completions.create({
|
|
112
135
|
model: this.modelName,
|
|
113
136
|
messages,
|
|
114
|
-
tools: functions,
|
|
115
|
-
tool_choice: options?.toolChoice ?? "auto",
|
|
116
137
|
reasoning_effort: options?.reasoning,
|
|
117
138
|
verbosity: options?.verbosity
|
|
118
139
|
});
|
|
119
|
-
|
|
120
|
-
const toolCalls = tool_calls?.map(
|
|
121
|
-
(value) => {
|
|
122
|
-
const v = value;
|
|
123
|
-
return {
|
|
124
|
-
name: v.function.name,
|
|
125
|
-
// FIXME: value.function.arguments could not be a valid JSON
|
|
126
|
-
arguments: JSON.parse(v.function.arguments)
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
);
|
|
140
|
+
this.logCallSuccess("fetch", startedAt);
|
|
130
141
|
return {
|
|
131
|
-
content: content || void 0
|
|
132
|
-
toolCalls
|
|
142
|
+
content: response.choices[0].message.content || void 0
|
|
133
143
|
};
|
|
144
|
+
} catch (error) {
|
|
145
|
+
this.logCallFailure("fetch", startedAt, error);
|
|
146
|
+
throw error;
|
|
134
147
|
}
|
|
135
|
-
|
|
148
|
+
}
|
|
149
|
+
async fetchWithContextMessage(messages, functions, options) {
|
|
150
|
+
if (functions.length > 0) {
|
|
151
|
+
const startedAt = Date.now();
|
|
152
|
+
this.logCallStart(
|
|
153
|
+
"fetchWithContextMessage",
|
|
154
|
+
messages.length,
|
|
155
|
+
functions.length
|
|
156
|
+
);
|
|
157
|
+
try {
|
|
158
|
+
const response = await this.client.chat.completions.create({
|
|
159
|
+
model: this.modelName,
|
|
160
|
+
messages,
|
|
161
|
+
tools: functions,
|
|
162
|
+
tool_choice: options?.toolChoice ?? "auto",
|
|
163
|
+
reasoning_effort: options?.reasoning,
|
|
164
|
+
verbosity: options?.verbosity
|
|
165
|
+
});
|
|
166
|
+
this.logCallSuccess("fetchWithContextMessage", startedAt);
|
|
167
|
+
const { content, tool_calls } = response.choices[0].message;
|
|
168
|
+
const toolCalls = tool_calls?.map(
|
|
169
|
+
(value) => {
|
|
170
|
+
const v = value;
|
|
171
|
+
let args;
|
|
172
|
+
try {
|
|
173
|
+
args = JSON.parse(v.function.arguments);
|
|
174
|
+
} catch {
|
|
175
|
+
args = { __raw: v.function.arguments };
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
name: v.function.name,
|
|
179
|
+
arguments: args
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
return {
|
|
184
|
+
content: content || void 0,
|
|
185
|
+
toolCalls
|
|
186
|
+
};
|
|
187
|
+
} catch (error) {
|
|
188
|
+
this.logCallFailure("fetchWithContextMessage", startedAt, error);
|
|
189
|
+
throw error;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return await this.fetch(messages, options);
|
|
136
193
|
}
|
|
137
194
|
async fetchStreamWithContextMessage(messages, functions, options) {
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
195
|
+
const startedAt = Date.now();
|
|
196
|
+
this.logCallStart(
|
|
197
|
+
"fetchStreamWithContextMessage",
|
|
198
|
+
messages.length,
|
|
199
|
+
functions.length
|
|
200
|
+
);
|
|
201
|
+
try {
|
|
202
|
+
const stream = await this.client.chat.completions.create({
|
|
203
|
+
model: this.modelName,
|
|
204
|
+
messages,
|
|
205
|
+
...functions.length > 0 ? {
|
|
206
|
+
tools: functions,
|
|
207
|
+
tool_choice: options?.toolChoice ?? "auto"
|
|
208
|
+
} : {},
|
|
209
|
+
stream: true,
|
|
210
|
+
reasoning_effort: options?.reasoning,
|
|
211
|
+
verbosity: options?.verbosity
|
|
212
|
+
});
|
|
213
|
+
return this.withStreamLogging(
|
|
214
|
+
this.createOpenAIStreamAdapter(stream),
|
|
215
|
+
"fetchStreamWithContextMessage",
|
|
216
|
+
startedAt
|
|
217
|
+
);
|
|
218
|
+
} catch (error) {
|
|
219
|
+
this.logCallFailure("fetchStreamWithContextMessage", startedAt, error);
|
|
220
|
+
throw error;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Wraps an LLMStream so the completion log covers the whole stream
|
|
225
|
+
* lifetime, not just the initial request.
|
|
226
|
+
*/
|
|
227
|
+
withStreamLogging(stream, method, startedAt) {
|
|
228
|
+
const logSuccess = () => this.logCallSuccess(method, startedAt);
|
|
229
|
+
const logFailure = (error) => this.logCallFailure(method, startedAt, error);
|
|
230
|
+
return {
|
|
231
|
+
...stream,
|
|
232
|
+
async *[Symbol.asyncIterator]() {
|
|
233
|
+
try {
|
|
234
|
+
yield* stream;
|
|
235
|
+
logSuccess();
|
|
236
|
+
} catch (error) {
|
|
237
|
+
logFailure(error);
|
|
238
|
+
throw error;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
};
|
|
148
242
|
}
|
|
149
243
|
// NOTE(yoojin): Need to switch API Stream type to LLMStream.
|
|
150
244
|
createOpenAIStreamAdapter(openaiStream) {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts"],"sourcesContent":["import {\n\ttype AssistantToolCallTurn,\n\tBaseModel,\n\ttype ModelFetchOptions,\n\ttype ToolResultMessage,\n} from \"@ainetwork/adk/modules\";\nimport type {\n\tConnectorTool,\n\tFetchResponse,\n\tToolCall,\n} from \"@ainetwork/adk/types/connector\";\nimport {\n\ttype MessageObject,\n\tMessageRole,\n\ttype ThreadObject,\n} from \"@ainetwork/adk/types/memory\";\nimport type {\n\tLLMStream,\n\tStreamChunk,\n\tToolCallDelta,\n} from \"@ainetwork/adk/types/stream\";\nimport { AzureOpenAI as AzureOpenAIClient } from \"openai\";\nimport type {\n\tChatCompletionMessageParam as CCMessageParam,\n\tChatCompletionChunk,\n\tChatCompletionMessageFunctionToolCall,\n\tChatCompletionMessageToolCall,\n\tChatCompletionTool,\n} from \"openai/resources\";\n\nexport interface AzureOpenAIConfig {\n\tendpoint?: string;\n\tdeployment?: string;\n\tbaseUrl?: string;\n\tapiKey: string;\n\tapiVersion: string;\n\tmodelName: string;\n}\n\nexport class AzureOpenAI extends BaseModel<CCMessageParam, ChatCompletionTool> {\n\tprivate client: AzureOpenAIClient;\n\tprivate modelName: string;\n\n\tconstructor({\n\t\tendpoint,\n\t\tdeployment,\n\t\tbaseUrl,\n\t\tapiKey,\n\t\tapiVersion,\n\t\tmodelName,\n\t}: AzureOpenAIConfig) {\n\t\tsuper();\n\t\tconst options = {\n\t\t\tendpoint,\n\t\t\tapiKey,\n\t\t\tdeployment,\n\t\t\tapiVersion,\n\t\t\tbaseURL: baseUrl,\n\t\t};\n\t\tthis.client = new AzureOpenAIClient(options);\n\t\tthis.modelName = modelName;\n\t}\n\n\tprivate getMessageRole(role: MessageRole) {\n\t\tswitch (role) {\n\t\t\tcase MessageRole.USER:\n\t\t\t\treturn \"user\";\n\t\t\tcase MessageRole.MODEL:\n\t\t\tcase MessageRole.SYSTEM:\n\t\t\t\treturn \"system\";\n\t\t\tdefault:\n\t\t\t\treturn \"system\"; /*FIXME*/\n\t\t}\n\t}\n\n\tgenerateMessages(params: {\n\t\tquery: string;\n\t\tthread?: ThreadObject;\n\t\tsystemPrompt?: string;\n\t}): CCMessageParam[] {\n\t\tconst { query, thread, systemPrompt } = params;\n\t\tconst messages: CCMessageParam[] = !systemPrompt\n\t\t\t? []\n\t\t\t: [{ role: \"system\", content: systemPrompt.trim() }];\n\t\tconst sessionContent: CCMessageParam[] = !thread\n\t\t\t? []\n\t\t\t: thread.messages.map((message: MessageObject) => {\n\t\t\t\t\t// Prefer the real query stashed in metadata when a display text was\n\t\t\t\t\t// shown in its place (displayQuery), so multi-turn history carries\n\t\t\t\t\t// the actual query the model saw on the first turn — not the short\n\t\t\t\t\t// label. Falls back to the stored content otherwise.\n\t\t\t\t\tconst content =\n\t\t\t\t\t\ttypeof message.metadata?.query === \"string\"\n\t\t\t\t\t\t\t? message.metadata.query\n\t\t\t\t\t\t\t: (message.content.parts[0] as string);\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: this.getMessageRole(message.role),\n\t\t\t\t\t\tcontent,\n\t\t\t\t\t};\n\t\t\t\t});\n\t\tconst userContent: CCMessageParam = { role: \"user\", content: query };\n\t\treturn messages.concat(sessionContent).concat(userContent);\n\t}\n\n\tappendAssistantToolCallTurn(\n\t\tmessages: CCMessageParam[],\n\t\tturn: AssistantToolCallTurn,\n\t): void {\n\t\tmessages.push({\n\t\t\trole: \"assistant\",\n\t\t\tcontent: turn.content,\n\t\t\ttool_calls: turn.toolCalls.map(\n\t\t\t\t(tc): ChatCompletionMessageFunctionToolCall => ({\n\t\t\t\t\tid: tc.id,\n\t\t\t\t\ttype: \"function\",\n\t\t\t\t\tfunction: {\n\t\t\t\t\t\tname: tc.function.name,\n\t\t\t\t\t\targuments: tc.function.arguments,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t),\n\t\t});\n\t}\n\n\tappendToolResult(\n\t\tmessages: CCMessageParam[],\n\t\tresult: ToolResultMessage,\n\t): void {\n\t\tmessages.push({\n\t\t\trole: \"tool\",\n\t\t\ttool_call_id: result.toolCallId,\n\t\t\tcontent: result.content,\n\t\t});\n\t}\n\n\tasync fetch(\n\t\tmessages: CCMessageParam[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<FetchResponse> {\n\t\tconst response = await this.client.chat.completions.create({\n\t\t\tmodel: this.modelName,\n\t\t\tmessages,\n\t\t\treasoning_effort: options?.reasoning,\n\t\t\tverbosity: options?.verbosity,\n\t\t});\n\n\t\treturn {\n\t\t\tcontent: response.choices[0].message.content || undefined,\n\t\t};\n\t}\n\n\tasync fetchWithContextMessage(\n\t\tmessages: CCMessageParam[],\n\t\tfunctions: ChatCompletionTool[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<FetchResponse> {\n\t\tif (functions.length > 0) {\n\t\t\tconst response = await this.client.chat.completions.create({\n\t\t\t\tmodel: this.modelName,\n\t\t\t\tmessages,\n\t\t\t\ttools: functions,\n\t\t\t\ttool_choice: options?.toolChoice ?? \"auto\",\n\t\t\t\treasoning_effort: options?.reasoning,\n\t\t\t\tverbosity: options?.verbosity,\n\t\t\t});\n\n\t\t\tconst { content, tool_calls } = response.choices[0].message;\n\n\t\t\tconst toolCalls: ToolCall[] | undefined = tool_calls?.map(\n\t\t\t\t(value: ChatCompletionMessageToolCall) => {\n\t\t\t\t\tconst v = value as ChatCompletionMessageFunctionToolCall;\n\t\t\t\t\treturn {\n\t\t\t\t\t\tname: v.function.name,\n\t\t\t\t\t\t// FIXME: value.function.arguments could not be a valid JSON\n\t\t\t\t\t\targuments: JSON.parse(v.function.arguments),\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\tcontent: content || undefined,\n\t\t\t\ttoolCalls,\n\t\t\t};\n\t\t}\n\t\treturn await this.fetch(messages);\n\t}\n\n\tasync fetchStreamWithContextMessage(\n\t\tmessages: CCMessageParam[],\n\t\tfunctions: ChatCompletionTool[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<LLMStream> {\n\t\tconst stream = await this.client.chat.completions.create({\n\t\t\tmodel: this.modelName,\n\t\t\tmessages,\n\t\t\ttools: functions,\n\t\t\ttool_choice:\n\t\t\t\tfunctions.length > 0 ? (options?.toolChoice ?? \"auto\") : \"none\",\n\t\t\tstream: true,\n\t\t\treasoning_effort: options?.reasoning,\n\t\t\tverbosity: options?.verbosity,\n\t\t});\n\t\treturn this.createOpenAIStreamAdapter(stream);\n\t}\n\n\t// NOTE(yoojin): Need to switch API Stream type to LLMStream.\n\tprivate createOpenAIStreamAdapter(\n\t\topenaiStream: AsyncIterable<ChatCompletionChunk>,\n\t): LLMStream {\n\t\treturn {\n\t\t\tasync *[Symbol.asyncIterator](): AsyncIterator<StreamChunk> {\n\t\t\t\tfor await (const openaiChunk of openaiStream) {\n\t\t\t\t\tconst choice = openaiChunk.choices[0];\n\t\t\t\t\tif (choice) {\n\t\t\t\t\t\tconst streamChunk: StreamChunk = {\n\t\t\t\t\t\t\tdelta: {\n\t\t\t\t\t\t\t\trole: choice.delta?.role || undefined,\n\t\t\t\t\t\t\t\tcontent: choice.delta?.content || undefined,\n\t\t\t\t\t\t\t\ttool_calls: choice.delta?.tool_calls?.map(\n\t\t\t\t\t\t\t\t\t(tc) =>\n\t\t\t\t\t\t\t\t\t\t({\n\t\t\t\t\t\t\t\t\t\t\tindex: tc.index,\n\t\t\t\t\t\t\t\t\t\t\tid: tc.id,\n\t\t\t\t\t\t\t\t\t\t\ttype: tc.type,\n\t\t\t\t\t\t\t\t\t\t\tfunction: tc.function,\n\t\t\t\t\t\t\t\t\t\t}) as ToolCallDelta,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tfinish_reason: choice.finish_reason as any,\n\t\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\t\tprovider: \"openai\",\n\t\t\t\t\t\t\t\tmodel: openaiChunk.model,\n\t\t\t\t\t\t\t\tid: openaiChunk.id,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t\tyield streamChunk;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tmetadata: { provider: \"openai\" },\n\t\t};\n\t}\n\n\tconvertToolsToFunctions(tools: ConnectorTool[]): ChatCompletionTool[] {\n\t\tconst functions: ChatCompletionTool[] = [];\n\t\tfor (const tool of tools) {\n\t\t\tfunctions.push({\n\t\t\t\ttype: \"function\",\n\t\t\t\tfunction: {\n\t\t\t\t\tname: tool.toolName,\n\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\tparameters: tool.inputSchema,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t\treturn functions;\n\t}\n}\n"],"mappings":"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","names":["AzureOpenAIClient"]}
|
|
1
|
+
{"version":3,"sources":["../index.ts"],"sourcesContent":["import {\n\ttype AssistantToolCallTurn,\n\tBaseModel,\n\ttype ModelFetchOptions,\n\ttype ToolResultMessage,\n} from \"@ainetwork/adk/modules\";\nimport type {\n\tConnectorTool,\n\tFetchResponse,\n\tToolCall,\n} from \"@ainetwork/adk/types/connector\";\nimport {\n\ttype MessageObject,\n\tMessageRole,\n\ttype ThreadObject,\n} from \"@ainetwork/adk/types/memory\";\nimport type {\n\tLLMStream,\n\tStreamChunk,\n\tToolCallDelta,\n} from \"@ainetwork/adk/types/stream\";\nimport { loggers } from \"@ainetwork/adk/utils/logger\";\nimport { AzureOpenAI as AzureOpenAIClient } from \"openai\";\nimport type {\n\tChatCompletionMessageParam as CCMessageParam,\n\tChatCompletionChunk,\n\tChatCompletionMessageFunctionToolCall,\n\tChatCompletionMessageToolCall,\n\tChatCompletionTool,\n} from \"openai/resources\";\n\nconst DEFAULT_TIMEOUT_MS = 120_000;\nconst DEFAULT_MAX_RETRIES = 1;\nconst PROVIDER = \"azure-openai\";\n\nexport interface AzureOpenAIConfig {\n\tendpoint?: string;\n\tdeployment?: string;\n\tbaseUrl?: string;\n\tapiKey: string;\n\tapiVersion: string;\n\tmodelName: string;\n\t/** Request timeout in milliseconds. Defaults to 120000 (2 minutes). */\n\ttimeout?: number;\n\t/** Maximum number of automatic retries. Defaults to 1. */\n\tmaxRetries?: number;\n}\n\nexport class AzureOpenAI extends BaseModel<CCMessageParam, ChatCompletionTool> {\n\tprivate client: AzureOpenAIClient;\n\tprivate modelName: string;\n\n\tconstructor({\n\t\tendpoint,\n\t\tdeployment,\n\t\tbaseUrl,\n\t\tapiKey,\n\t\tapiVersion,\n\t\tmodelName,\n\t\ttimeout = DEFAULT_TIMEOUT_MS,\n\t\tmaxRetries = DEFAULT_MAX_RETRIES,\n\t}: AzureOpenAIConfig) {\n\t\tsuper();\n\t\tconst options = {\n\t\t\tendpoint,\n\t\t\tapiKey,\n\t\t\tdeployment,\n\t\t\tapiVersion,\n\t\t\tbaseURL: baseUrl,\n\t\t\ttimeout,\n\t\t\tmaxRetries,\n\t\t};\n\t\tthis.client = new AzureOpenAIClient(options);\n\t\tthis.modelName = modelName;\n\t}\n\n\tprivate getMessageRole(role: MessageRole) {\n\t\tswitch (role) {\n\t\t\tcase MessageRole.USER:\n\t\t\t\treturn \"user\";\n\t\t\tcase MessageRole.MODEL:\n\t\t\t\treturn \"assistant\";\n\t\t\tcase MessageRole.SYSTEM:\n\t\t\t\treturn \"system\";\n\t\t\tdefault:\n\t\t\t\treturn \"system\";\n\t\t}\n\t}\n\n\tprivate logCallStart(method: string, messageCount: number, toolCount = 0) {\n\t\tloggers.model.debug(`[${PROVIDER}] ${method} start`, {\n\t\t\tprovider: PROVIDER,\n\t\t\tmodel: this.modelName,\n\t\t\tmessageCount,\n\t\t\ttoolCount,\n\t\t});\n\t}\n\n\tprivate logCallSuccess(method: string, startedAt: number) {\n\t\tloggers.model.info(`[${PROVIDER}] ${method} complete`, {\n\t\t\tprovider: PROVIDER,\n\t\t\tmodel: this.modelName,\n\t\t\tdurationMs: Date.now() - startedAt,\n\t\t});\n\t}\n\n\tprivate logCallFailure(method: string, startedAt: number, error: unknown) {\n\t\tloggers.model.error(`[${PROVIDER}] ${method} failed`, {\n\t\t\tprovider: PROVIDER,\n\t\t\tmodel: this.modelName,\n\t\t\tdurationMs: Date.now() - startedAt,\n\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t});\n\t}\n\n\tgenerateMessages(params: {\n\t\tquery: string;\n\t\tthread?: ThreadObject;\n\t\tsystemPrompt?: string;\n\t}): CCMessageParam[] {\n\t\tconst { query, thread, systemPrompt } = params;\n\t\tconst messages: CCMessageParam[] = !systemPrompt\n\t\t\t? []\n\t\t\t: [{ role: \"system\", content: systemPrompt.trim() }];\n\t\tconst sessionContent: CCMessageParam[] = !thread\n\t\t\t? []\n\t\t\t: thread.messages.map((message: MessageObject) => {\n\t\t\t\t\t// Prefer the real query stashed in metadata when a display text was\n\t\t\t\t\t// shown in its place (displayQuery), so multi-turn history carries\n\t\t\t\t\t// the actual query the model saw on the first turn — not the short\n\t\t\t\t\t// label. Falls back to the stored content otherwise.\n\t\t\t\t\tconst content =\n\t\t\t\t\t\ttypeof message.metadata?.query === \"string\"\n\t\t\t\t\t\t\t? message.metadata.query\n\t\t\t\t\t\t\t: (message.content.parts[0] as string);\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: this.getMessageRole(message.role),\n\t\t\t\t\t\tcontent,\n\t\t\t\t\t};\n\t\t\t\t});\n\t\tconst userContent: CCMessageParam = { role: \"user\", content: query };\n\t\treturn messages.concat(sessionContent).concat(userContent);\n\t}\n\n\tappendAssistantToolCallTurn(\n\t\tmessages: CCMessageParam[],\n\t\tturn: AssistantToolCallTurn,\n\t): void {\n\t\tmessages.push({\n\t\t\trole: \"assistant\",\n\t\t\tcontent: turn.content,\n\t\t\ttool_calls: turn.toolCalls.map(\n\t\t\t\t(tc): ChatCompletionMessageFunctionToolCall => ({\n\t\t\t\t\tid: tc.id,\n\t\t\t\t\ttype: \"function\",\n\t\t\t\t\tfunction: {\n\t\t\t\t\t\tname: tc.function.name,\n\t\t\t\t\t\targuments: tc.function.arguments,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t),\n\t\t});\n\t}\n\n\tappendToolResult(\n\t\tmessages: CCMessageParam[],\n\t\tresult: ToolResultMessage,\n\t): void {\n\t\tmessages.push({\n\t\t\trole: \"tool\",\n\t\t\ttool_call_id: result.toolCallId,\n\t\t\tcontent: result.content,\n\t\t});\n\t}\n\n\tasync fetch(\n\t\tmessages: CCMessageParam[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<FetchResponse> {\n\t\tconst startedAt = Date.now();\n\t\tthis.logCallStart(\"fetch\", messages.length);\n\t\ttry {\n\t\t\tconst response = await this.client.chat.completions.create({\n\t\t\t\tmodel: this.modelName,\n\t\t\t\tmessages,\n\t\t\t\treasoning_effort: options?.reasoning,\n\t\t\t\tverbosity: options?.verbosity,\n\t\t\t});\n\t\t\tthis.logCallSuccess(\"fetch\", startedAt);\n\n\t\t\treturn {\n\t\t\t\tcontent: response.choices[0].message.content || undefined,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthis.logCallFailure(\"fetch\", startedAt, error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync fetchWithContextMessage(\n\t\tmessages: CCMessageParam[],\n\t\tfunctions: ChatCompletionTool[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<FetchResponse> {\n\t\tif (functions.length > 0) {\n\t\t\tconst startedAt = Date.now();\n\t\t\tthis.logCallStart(\n\t\t\t\t\"fetchWithContextMessage\",\n\t\t\t\tmessages.length,\n\t\t\t\tfunctions.length,\n\t\t\t);\n\t\t\ttry {\n\t\t\t\tconst response = await this.client.chat.completions.create({\n\t\t\t\t\tmodel: this.modelName,\n\t\t\t\t\tmessages,\n\t\t\t\t\ttools: functions,\n\t\t\t\t\ttool_choice: options?.toolChoice ?? \"auto\",\n\t\t\t\t\treasoning_effort: options?.reasoning,\n\t\t\t\t\tverbosity: options?.verbosity,\n\t\t\t\t});\n\t\t\t\tthis.logCallSuccess(\"fetchWithContextMessage\", startedAt);\n\n\t\t\t\tconst { content, tool_calls } = response.choices[0].message;\n\n\t\t\t\tconst toolCalls: ToolCall[] | undefined = tool_calls?.map(\n\t\t\t\t\t(value: ChatCompletionMessageToolCall) => {\n\t\t\t\t\t\tconst v = value as ChatCompletionMessageFunctionToolCall;\n\t\t\t\t\t\tlet args: Record<string, unknown>;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\targs = JSON.parse(v.function.arguments);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// Forward the raw argument string so the caller can surface it\n\t\t\t\t\t\t\t// (and the model can self-correct) instead of killing the fetch.\n\t\t\t\t\t\t\targs = { __raw: v.function.arguments };\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tname: v.function.name,\n\t\t\t\t\t\t\targuments: args,\n\t\t\t\t\t\t};\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\treturn {\n\t\t\t\t\tcontent: content || undefined,\n\t\t\t\t\ttoolCalls,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tthis.logCallFailure(\"fetchWithContextMessage\", startedAt, error);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\treturn await this.fetch(messages, options);\n\t}\n\n\tasync fetchStreamWithContextMessage(\n\t\tmessages: CCMessageParam[],\n\t\tfunctions: ChatCompletionTool[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<LLMStream> {\n\t\tconst startedAt = Date.now();\n\t\tthis.logCallStart(\n\t\t\t\"fetchStreamWithContextMessage\",\n\t\t\tmessages.length,\n\t\t\tfunctions.length,\n\t\t);\n\t\ttry {\n\t\t\tconst stream = await this.client.chat.completions.create({\n\t\t\t\tmodel: this.modelName,\n\t\t\t\tmessages,\n\t\t\t\t...(functions.length > 0\n\t\t\t\t\t? {\n\t\t\t\t\t\t\ttools: functions,\n\t\t\t\t\t\t\ttool_choice: options?.toolChoice ?? \"auto\",\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t\tstream: true,\n\t\t\t\treasoning_effort: options?.reasoning,\n\t\t\t\tverbosity: options?.verbosity,\n\t\t\t});\n\t\t\treturn this.withStreamLogging(\n\t\t\t\tthis.createOpenAIStreamAdapter(stream),\n\t\t\t\t\"fetchStreamWithContextMessage\",\n\t\t\t\tstartedAt,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthis.logCallFailure(\"fetchStreamWithContextMessage\", startedAt, error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Wraps an LLMStream so the completion log covers the whole stream\n\t * lifetime, not just the initial request.\n\t */\n\tprivate withStreamLogging(\n\t\tstream: LLMStream,\n\t\tmethod: string,\n\t\tstartedAt: number,\n\t): LLMStream {\n\t\tconst logSuccess = () => this.logCallSuccess(method, startedAt);\n\t\tconst logFailure = (error: unknown) =>\n\t\t\tthis.logCallFailure(method, startedAt, error);\n\t\treturn {\n\t\t\t...stream,\n\t\t\tasync *[Symbol.asyncIterator](): AsyncIterator<StreamChunk> {\n\t\t\t\ttry {\n\t\t\t\t\tyield* stream;\n\t\t\t\t\tlogSuccess();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlogFailure(error);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t}\n\n\t// NOTE(yoojin): Need to switch API Stream type to LLMStream.\n\tprivate createOpenAIStreamAdapter(\n\t\topenaiStream: AsyncIterable<ChatCompletionChunk>,\n\t): LLMStream {\n\t\treturn {\n\t\t\tasync *[Symbol.asyncIterator](): AsyncIterator<StreamChunk> {\n\t\t\t\tfor await (const openaiChunk of openaiStream) {\n\t\t\t\t\tconst choice = openaiChunk.choices[0];\n\t\t\t\t\tif (choice) {\n\t\t\t\t\t\tconst streamChunk: StreamChunk = {\n\t\t\t\t\t\t\tdelta: {\n\t\t\t\t\t\t\t\trole: choice.delta?.role || undefined,\n\t\t\t\t\t\t\t\tcontent: choice.delta?.content || undefined,\n\t\t\t\t\t\t\t\ttool_calls: choice.delta?.tool_calls?.map(\n\t\t\t\t\t\t\t\t\t(tc) =>\n\t\t\t\t\t\t\t\t\t\t({\n\t\t\t\t\t\t\t\t\t\t\tindex: tc.index,\n\t\t\t\t\t\t\t\t\t\t\tid: tc.id,\n\t\t\t\t\t\t\t\t\t\t\ttype: tc.type,\n\t\t\t\t\t\t\t\t\t\t\tfunction: tc.function,\n\t\t\t\t\t\t\t\t\t\t}) as ToolCallDelta,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tfinish_reason: choice.finish_reason as any,\n\t\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\t\tprovider: \"openai\",\n\t\t\t\t\t\t\t\tmodel: openaiChunk.model,\n\t\t\t\t\t\t\t\tid: openaiChunk.id,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t\tyield streamChunk;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tmetadata: { provider: \"openai\" },\n\t\t};\n\t}\n\n\tconvertToolsToFunctions(tools: ConnectorTool[]): ChatCompletionTool[] {\n\t\tconst functions: ChatCompletionTool[] = [];\n\t\tfor (const tool of tools) {\n\t\t\tfunctions.push({\n\t\t\t\ttype: \"function\",\n\t\t\t\tfunction: {\n\t\t\t\t\tname: tool.toolName,\n\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\tparameters: tool.inputSchema,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t\treturn functions;\n\t}\n}\n"],"mappings":"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","names":["AzureOpenAIClient"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -11,12 +11,19 @@ interface AzureOpenAIConfig {
|
|
|
11
11
|
apiKey: string;
|
|
12
12
|
apiVersion: string;
|
|
13
13
|
modelName: string;
|
|
14
|
+
/** Request timeout in milliseconds. Defaults to 120000 (2 minutes). */
|
|
15
|
+
timeout?: number;
|
|
16
|
+
/** Maximum number of automatic retries. Defaults to 1. */
|
|
17
|
+
maxRetries?: number;
|
|
14
18
|
}
|
|
15
19
|
declare class AzureOpenAI extends BaseModel<ChatCompletionMessageParam, ChatCompletionTool> {
|
|
16
20
|
private client;
|
|
17
21
|
private modelName;
|
|
18
|
-
constructor({ endpoint, deployment, baseUrl, apiKey, apiVersion, modelName, }: AzureOpenAIConfig);
|
|
22
|
+
constructor({ endpoint, deployment, baseUrl, apiKey, apiVersion, modelName, timeout, maxRetries, }: AzureOpenAIConfig);
|
|
19
23
|
private getMessageRole;
|
|
24
|
+
private logCallStart;
|
|
25
|
+
private logCallSuccess;
|
|
26
|
+
private logCallFailure;
|
|
20
27
|
generateMessages(params: {
|
|
21
28
|
query: string;
|
|
22
29
|
thread?: ThreadObject;
|
|
@@ -27,6 +34,11 @@ declare class AzureOpenAI extends BaseModel<ChatCompletionMessageParam, ChatComp
|
|
|
27
34
|
fetch(messages: ChatCompletionMessageParam[], options?: ModelFetchOptions): Promise<FetchResponse>;
|
|
28
35
|
fetchWithContextMessage(messages: ChatCompletionMessageParam[], functions: ChatCompletionTool[], options?: ModelFetchOptions): Promise<FetchResponse>;
|
|
29
36
|
fetchStreamWithContextMessage(messages: ChatCompletionMessageParam[], functions: ChatCompletionTool[], options?: ModelFetchOptions): Promise<LLMStream>;
|
|
37
|
+
/**
|
|
38
|
+
* Wraps an LLMStream so the completion log covers the whole stream
|
|
39
|
+
* lifetime, not just the initial request.
|
|
40
|
+
*/
|
|
41
|
+
private withStreamLogging;
|
|
30
42
|
private createOpenAIStreamAdapter;
|
|
31
43
|
convertToolsToFunctions(tools: ConnectorTool[]): ChatCompletionTool[];
|
|
32
44
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,12 +11,19 @@ interface AzureOpenAIConfig {
|
|
|
11
11
|
apiKey: string;
|
|
12
12
|
apiVersion: string;
|
|
13
13
|
modelName: string;
|
|
14
|
+
/** Request timeout in milliseconds. Defaults to 120000 (2 minutes). */
|
|
15
|
+
timeout?: number;
|
|
16
|
+
/** Maximum number of automatic retries. Defaults to 1. */
|
|
17
|
+
maxRetries?: number;
|
|
14
18
|
}
|
|
15
19
|
declare class AzureOpenAI extends BaseModel<ChatCompletionMessageParam, ChatCompletionTool> {
|
|
16
20
|
private client;
|
|
17
21
|
private modelName;
|
|
18
|
-
constructor({ endpoint, deployment, baseUrl, apiKey, apiVersion, modelName, }: AzureOpenAIConfig);
|
|
22
|
+
constructor({ endpoint, deployment, baseUrl, apiKey, apiVersion, modelName, timeout, maxRetries, }: AzureOpenAIConfig);
|
|
19
23
|
private getMessageRole;
|
|
24
|
+
private logCallStart;
|
|
25
|
+
private logCallSuccess;
|
|
26
|
+
private logCallFailure;
|
|
20
27
|
generateMessages(params: {
|
|
21
28
|
query: string;
|
|
22
29
|
thread?: ThreadObject;
|
|
@@ -27,6 +34,11 @@ declare class AzureOpenAI extends BaseModel<ChatCompletionMessageParam, ChatComp
|
|
|
27
34
|
fetch(messages: ChatCompletionMessageParam[], options?: ModelFetchOptions): Promise<FetchResponse>;
|
|
28
35
|
fetchWithContextMessage(messages: ChatCompletionMessageParam[], functions: ChatCompletionTool[], options?: ModelFetchOptions): Promise<FetchResponse>;
|
|
29
36
|
fetchStreamWithContextMessage(messages: ChatCompletionMessageParam[], functions: ChatCompletionTool[], options?: ModelFetchOptions): Promise<LLMStream>;
|
|
37
|
+
/**
|
|
38
|
+
* Wraps an LLMStream so the completion log covers the whole stream
|
|
39
|
+
* lifetime, not just the initial request.
|
|
40
|
+
*/
|
|
41
|
+
private withStreamLogging;
|
|
30
42
|
private createOpenAIStreamAdapter;
|
|
31
43
|
convertToolsToFunctions(tools: ConnectorTool[]): ChatCompletionTool[];
|
|
32
44
|
}
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,11 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
MessageRole
|
|
7
7
|
} from "@ainetwork/adk/types/memory";
|
|
8
|
+
import { loggers } from "@ainetwork/adk/utils/logger";
|
|
8
9
|
import { AzureOpenAI as AzureOpenAIClient } from "openai";
|
|
10
|
+
var DEFAULT_TIMEOUT_MS = 12e4;
|
|
11
|
+
var DEFAULT_MAX_RETRIES = 1;
|
|
12
|
+
var PROVIDER = "azure-openai";
|
|
9
13
|
var AzureOpenAI = class extends BaseModel {
|
|
10
14
|
client;
|
|
11
15
|
modelName;
|
|
@@ -15,7 +19,9 @@ var AzureOpenAI = class extends BaseModel {
|
|
|
15
19
|
baseUrl,
|
|
16
20
|
apiKey,
|
|
17
21
|
apiVersion,
|
|
18
|
-
modelName
|
|
22
|
+
modelName,
|
|
23
|
+
timeout = DEFAULT_TIMEOUT_MS,
|
|
24
|
+
maxRetries = DEFAULT_MAX_RETRIES
|
|
19
25
|
}) {
|
|
20
26
|
super();
|
|
21
27
|
const options = {
|
|
@@ -23,7 +29,9 @@ var AzureOpenAI = class extends BaseModel {
|
|
|
23
29
|
apiKey,
|
|
24
30
|
deployment,
|
|
25
31
|
apiVersion,
|
|
26
|
-
baseURL: baseUrl
|
|
32
|
+
baseURL: baseUrl,
|
|
33
|
+
timeout,
|
|
34
|
+
maxRetries
|
|
27
35
|
};
|
|
28
36
|
this.client = new AzureOpenAIClient(options);
|
|
29
37
|
this.modelName = modelName;
|
|
@@ -33,12 +41,36 @@ var AzureOpenAI = class extends BaseModel {
|
|
|
33
41
|
case MessageRole.USER:
|
|
34
42
|
return "user";
|
|
35
43
|
case MessageRole.MODEL:
|
|
44
|
+
return "assistant";
|
|
36
45
|
case MessageRole.SYSTEM:
|
|
37
46
|
return "system";
|
|
38
47
|
default:
|
|
39
48
|
return "system";
|
|
40
49
|
}
|
|
41
50
|
}
|
|
51
|
+
logCallStart(method, messageCount, toolCount = 0) {
|
|
52
|
+
loggers.model.debug(`[${PROVIDER}] ${method} start`, {
|
|
53
|
+
provider: PROVIDER,
|
|
54
|
+
model: this.modelName,
|
|
55
|
+
messageCount,
|
|
56
|
+
toolCount
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
logCallSuccess(method, startedAt) {
|
|
60
|
+
loggers.model.info(`[${PROVIDER}] ${method} complete`, {
|
|
61
|
+
provider: PROVIDER,
|
|
62
|
+
model: this.modelName,
|
|
63
|
+
durationMs: Date.now() - startedAt
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
logCallFailure(method, startedAt, error) {
|
|
67
|
+
loggers.model.error(`[${PROVIDER}] ${method} failed`, {
|
|
68
|
+
provider: PROVIDER,
|
|
69
|
+
model: this.modelName,
|
|
70
|
+
durationMs: Date.now() - startedAt,
|
|
71
|
+
error: error instanceof Error ? error.message : String(error)
|
|
72
|
+
});
|
|
73
|
+
}
|
|
42
74
|
generateMessages(params) {
|
|
43
75
|
const { query, thread, systemPrompt } = params;
|
|
44
76
|
const messages = !systemPrompt ? [] : [{ role: "system", content: systemPrompt.trim() }];
|
|
@@ -76,55 +108,117 @@ var AzureOpenAI = class extends BaseModel {
|
|
|
76
108
|
});
|
|
77
109
|
}
|
|
78
110
|
async fetch(messages, options) {
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
reasoning_effort: options?.reasoning,
|
|
83
|
-
verbosity: options?.verbosity
|
|
84
|
-
});
|
|
85
|
-
return {
|
|
86
|
-
content: response.choices[0].message.content || void 0
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
async fetchWithContextMessage(messages, functions, options) {
|
|
90
|
-
if (functions.length > 0) {
|
|
111
|
+
const startedAt = Date.now();
|
|
112
|
+
this.logCallStart("fetch", messages.length);
|
|
113
|
+
try {
|
|
91
114
|
const response = await this.client.chat.completions.create({
|
|
92
115
|
model: this.modelName,
|
|
93
116
|
messages,
|
|
94
|
-
tools: functions,
|
|
95
|
-
tool_choice: options?.toolChoice ?? "auto",
|
|
96
117
|
reasoning_effort: options?.reasoning,
|
|
97
118
|
verbosity: options?.verbosity
|
|
98
119
|
});
|
|
99
|
-
|
|
100
|
-
const toolCalls = tool_calls?.map(
|
|
101
|
-
(value) => {
|
|
102
|
-
const v = value;
|
|
103
|
-
return {
|
|
104
|
-
name: v.function.name,
|
|
105
|
-
// FIXME: value.function.arguments could not be a valid JSON
|
|
106
|
-
arguments: JSON.parse(v.function.arguments)
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
);
|
|
120
|
+
this.logCallSuccess("fetch", startedAt);
|
|
110
121
|
return {
|
|
111
|
-
content: content || void 0
|
|
112
|
-
toolCalls
|
|
122
|
+
content: response.choices[0].message.content || void 0
|
|
113
123
|
};
|
|
124
|
+
} catch (error) {
|
|
125
|
+
this.logCallFailure("fetch", startedAt, error);
|
|
126
|
+
throw error;
|
|
114
127
|
}
|
|
115
|
-
|
|
128
|
+
}
|
|
129
|
+
async fetchWithContextMessage(messages, functions, options) {
|
|
130
|
+
if (functions.length > 0) {
|
|
131
|
+
const startedAt = Date.now();
|
|
132
|
+
this.logCallStart(
|
|
133
|
+
"fetchWithContextMessage",
|
|
134
|
+
messages.length,
|
|
135
|
+
functions.length
|
|
136
|
+
);
|
|
137
|
+
try {
|
|
138
|
+
const response = await this.client.chat.completions.create({
|
|
139
|
+
model: this.modelName,
|
|
140
|
+
messages,
|
|
141
|
+
tools: functions,
|
|
142
|
+
tool_choice: options?.toolChoice ?? "auto",
|
|
143
|
+
reasoning_effort: options?.reasoning,
|
|
144
|
+
verbosity: options?.verbosity
|
|
145
|
+
});
|
|
146
|
+
this.logCallSuccess("fetchWithContextMessage", startedAt);
|
|
147
|
+
const { content, tool_calls } = response.choices[0].message;
|
|
148
|
+
const toolCalls = tool_calls?.map(
|
|
149
|
+
(value) => {
|
|
150
|
+
const v = value;
|
|
151
|
+
let args;
|
|
152
|
+
try {
|
|
153
|
+
args = JSON.parse(v.function.arguments);
|
|
154
|
+
} catch {
|
|
155
|
+
args = { __raw: v.function.arguments };
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
name: v.function.name,
|
|
159
|
+
arguments: args
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
);
|
|
163
|
+
return {
|
|
164
|
+
content: content || void 0,
|
|
165
|
+
toolCalls
|
|
166
|
+
};
|
|
167
|
+
} catch (error) {
|
|
168
|
+
this.logCallFailure("fetchWithContextMessage", startedAt, error);
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return await this.fetch(messages, options);
|
|
116
173
|
}
|
|
117
174
|
async fetchStreamWithContextMessage(messages, functions, options) {
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
175
|
+
const startedAt = Date.now();
|
|
176
|
+
this.logCallStart(
|
|
177
|
+
"fetchStreamWithContextMessage",
|
|
178
|
+
messages.length,
|
|
179
|
+
functions.length
|
|
180
|
+
);
|
|
181
|
+
try {
|
|
182
|
+
const stream = await this.client.chat.completions.create({
|
|
183
|
+
model: this.modelName,
|
|
184
|
+
messages,
|
|
185
|
+
...functions.length > 0 ? {
|
|
186
|
+
tools: functions,
|
|
187
|
+
tool_choice: options?.toolChoice ?? "auto"
|
|
188
|
+
} : {},
|
|
189
|
+
stream: true,
|
|
190
|
+
reasoning_effort: options?.reasoning,
|
|
191
|
+
verbosity: options?.verbosity
|
|
192
|
+
});
|
|
193
|
+
return this.withStreamLogging(
|
|
194
|
+
this.createOpenAIStreamAdapter(stream),
|
|
195
|
+
"fetchStreamWithContextMessage",
|
|
196
|
+
startedAt
|
|
197
|
+
);
|
|
198
|
+
} catch (error) {
|
|
199
|
+
this.logCallFailure("fetchStreamWithContextMessage", startedAt, error);
|
|
200
|
+
throw error;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Wraps an LLMStream so the completion log covers the whole stream
|
|
205
|
+
* lifetime, not just the initial request.
|
|
206
|
+
*/
|
|
207
|
+
withStreamLogging(stream, method, startedAt) {
|
|
208
|
+
const logSuccess = () => this.logCallSuccess(method, startedAt);
|
|
209
|
+
const logFailure = (error) => this.logCallFailure(method, startedAt, error);
|
|
210
|
+
return {
|
|
211
|
+
...stream,
|
|
212
|
+
async *[Symbol.asyncIterator]() {
|
|
213
|
+
try {
|
|
214
|
+
yield* stream;
|
|
215
|
+
logSuccess();
|
|
216
|
+
} catch (error) {
|
|
217
|
+
logFailure(error);
|
|
218
|
+
throw error;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
};
|
|
128
222
|
}
|
|
129
223
|
// NOTE(yoojin): Need to switch API Stream type to LLMStream.
|
|
130
224
|
createOpenAIStreamAdapter(openaiStream) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts"],"sourcesContent":["import {\n\ttype AssistantToolCallTurn,\n\tBaseModel,\n\ttype ModelFetchOptions,\n\ttype ToolResultMessage,\n} from \"@ainetwork/adk/modules\";\nimport type {\n\tConnectorTool,\n\tFetchResponse,\n\tToolCall,\n} from \"@ainetwork/adk/types/connector\";\nimport {\n\ttype MessageObject,\n\tMessageRole,\n\ttype ThreadObject,\n} from \"@ainetwork/adk/types/memory\";\nimport type {\n\tLLMStream,\n\tStreamChunk,\n\tToolCallDelta,\n} from \"@ainetwork/adk/types/stream\";\nimport { AzureOpenAI as AzureOpenAIClient } from \"openai\";\nimport type {\n\tChatCompletionMessageParam as CCMessageParam,\n\tChatCompletionChunk,\n\tChatCompletionMessageFunctionToolCall,\n\tChatCompletionMessageToolCall,\n\tChatCompletionTool,\n} from \"openai/resources\";\n\nexport interface AzureOpenAIConfig {\n\tendpoint?: string;\n\tdeployment?: string;\n\tbaseUrl?: string;\n\tapiKey: string;\n\tapiVersion: string;\n\tmodelName: string;\n}\n\nexport class AzureOpenAI extends BaseModel<CCMessageParam, ChatCompletionTool> {\n\tprivate client: AzureOpenAIClient;\n\tprivate modelName: string;\n\n\tconstructor({\n\t\tendpoint,\n\t\tdeployment,\n\t\tbaseUrl,\n\t\tapiKey,\n\t\tapiVersion,\n\t\tmodelName,\n\t}: AzureOpenAIConfig) {\n\t\tsuper();\n\t\tconst options = {\n\t\t\tendpoint,\n\t\t\tapiKey,\n\t\t\tdeployment,\n\t\t\tapiVersion,\n\t\t\tbaseURL: baseUrl,\n\t\t};\n\t\tthis.client = new AzureOpenAIClient(options);\n\t\tthis.modelName = modelName;\n\t}\n\n\tprivate getMessageRole(role: MessageRole) {\n\t\tswitch (role) {\n\t\t\tcase MessageRole.USER:\n\t\t\t\treturn \"user\";\n\t\t\tcase MessageRole.MODEL:\n\t\t\tcase MessageRole.SYSTEM:\n\t\t\t\treturn \"system\";\n\t\t\tdefault:\n\t\t\t\treturn \"system\"; /*FIXME*/\n\t\t}\n\t}\n\n\tgenerateMessages(params: {\n\t\tquery: string;\n\t\tthread?: ThreadObject;\n\t\tsystemPrompt?: string;\n\t}): CCMessageParam[] {\n\t\tconst { query, thread, systemPrompt } = params;\n\t\tconst messages: CCMessageParam[] = !systemPrompt\n\t\t\t? []\n\t\t\t: [{ role: \"system\", content: systemPrompt.trim() }];\n\t\tconst sessionContent: CCMessageParam[] = !thread\n\t\t\t? []\n\t\t\t: thread.messages.map((message: MessageObject) => {\n\t\t\t\t\t// Prefer the real query stashed in metadata when a display text was\n\t\t\t\t\t// shown in its place (displayQuery), so multi-turn history carries\n\t\t\t\t\t// the actual query the model saw on the first turn — not the short\n\t\t\t\t\t// label. Falls back to the stored content otherwise.\n\t\t\t\t\tconst content =\n\t\t\t\t\t\ttypeof message.metadata?.query === \"string\"\n\t\t\t\t\t\t\t? message.metadata.query\n\t\t\t\t\t\t\t: (message.content.parts[0] as string);\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: this.getMessageRole(message.role),\n\t\t\t\t\t\tcontent,\n\t\t\t\t\t};\n\t\t\t\t});\n\t\tconst userContent: CCMessageParam = { role: \"user\", content: query };\n\t\treturn messages.concat(sessionContent).concat(userContent);\n\t}\n\n\tappendAssistantToolCallTurn(\n\t\tmessages: CCMessageParam[],\n\t\tturn: AssistantToolCallTurn,\n\t): void {\n\t\tmessages.push({\n\t\t\trole: \"assistant\",\n\t\t\tcontent: turn.content,\n\t\t\ttool_calls: turn.toolCalls.map(\n\t\t\t\t(tc): ChatCompletionMessageFunctionToolCall => ({\n\t\t\t\t\tid: tc.id,\n\t\t\t\t\ttype: \"function\",\n\t\t\t\t\tfunction: {\n\t\t\t\t\t\tname: tc.function.name,\n\t\t\t\t\t\targuments: tc.function.arguments,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t),\n\t\t});\n\t}\n\n\tappendToolResult(\n\t\tmessages: CCMessageParam[],\n\t\tresult: ToolResultMessage,\n\t): void {\n\t\tmessages.push({\n\t\t\trole: \"tool\",\n\t\t\ttool_call_id: result.toolCallId,\n\t\t\tcontent: result.content,\n\t\t});\n\t}\n\n\tasync fetch(\n\t\tmessages: CCMessageParam[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<FetchResponse> {\n\t\tconst response = await this.client.chat.completions.create({\n\t\t\tmodel: this.modelName,\n\t\t\tmessages,\n\t\t\treasoning_effort: options?.reasoning,\n\t\t\tverbosity: options?.verbosity,\n\t\t});\n\n\t\treturn {\n\t\t\tcontent: response.choices[0].message.content || undefined,\n\t\t};\n\t}\n\n\tasync fetchWithContextMessage(\n\t\tmessages: CCMessageParam[],\n\t\tfunctions: ChatCompletionTool[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<FetchResponse> {\n\t\tif (functions.length > 0) {\n\t\t\tconst response = await this.client.chat.completions.create({\n\t\t\t\tmodel: this.modelName,\n\t\t\t\tmessages,\n\t\t\t\ttools: functions,\n\t\t\t\ttool_choice: options?.toolChoice ?? \"auto\",\n\t\t\t\treasoning_effort: options?.reasoning,\n\t\t\t\tverbosity: options?.verbosity,\n\t\t\t});\n\n\t\t\tconst { content, tool_calls } = response.choices[0].message;\n\n\t\t\tconst toolCalls: ToolCall[] | undefined = tool_calls?.map(\n\t\t\t\t(value: ChatCompletionMessageToolCall) => {\n\t\t\t\t\tconst v = value as ChatCompletionMessageFunctionToolCall;\n\t\t\t\t\treturn {\n\t\t\t\t\t\tname: v.function.name,\n\t\t\t\t\t\t// FIXME: value.function.arguments could not be a valid JSON\n\t\t\t\t\t\targuments: JSON.parse(v.function.arguments),\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\tcontent: content || undefined,\n\t\t\t\ttoolCalls,\n\t\t\t};\n\t\t}\n\t\treturn await this.fetch(messages);\n\t}\n\n\tasync fetchStreamWithContextMessage(\n\t\tmessages: CCMessageParam[],\n\t\tfunctions: ChatCompletionTool[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<LLMStream> {\n\t\tconst stream = await this.client.chat.completions.create({\n\t\t\tmodel: this.modelName,\n\t\t\tmessages,\n\t\t\ttools: functions,\n\t\t\ttool_choice:\n\t\t\t\tfunctions.length > 0 ? (options?.toolChoice ?? \"auto\") : \"none\",\n\t\t\tstream: true,\n\t\t\treasoning_effort: options?.reasoning,\n\t\t\tverbosity: options?.verbosity,\n\t\t});\n\t\treturn this.createOpenAIStreamAdapter(stream);\n\t}\n\n\t// NOTE(yoojin): Need to switch API Stream type to LLMStream.\n\tprivate createOpenAIStreamAdapter(\n\t\topenaiStream: AsyncIterable<ChatCompletionChunk>,\n\t): LLMStream {\n\t\treturn {\n\t\t\tasync *[Symbol.asyncIterator](): AsyncIterator<StreamChunk> {\n\t\t\t\tfor await (const openaiChunk of openaiStream) {\n\t\t\t\t\tconst choice = openaiChunk.choices[0];\n\t\t\t\t\tif (choice) {\n\t\t\t\t\t\tconst streamChunk: StreamChunk = {\n\t\t\t\t\t\t\tdelta: {\n\t\t\t\t\t\t\t\trole: choice.delta?.role || undefined,\n\t\t\t\t\t\t\t\tcontent: choice.delta?.content || undefined,\n\t\t\t\t\t\t\t\ttool_calls: choice.delta?.tool_calls?.map(\n\t\t\t\t\t\t\t\t\t(tc) =>\n\t\t\t\t\t\t\t\t\t\t({\n\t\t\t\t\t\t\t\t\t\t\tindex: tc.index,\n\t\t\t\t\t\t\t\t\t\t\tid: tc.id,\n\t\t\t\t\t\t\t\t\t\t\ttype: tc.type,\n\t\t\t\t\t\t\t\t\t\t\tfunction: tc.function,\n\t\t\t\t\t\t\t\t\t\t}) as ToolCallDelta,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tfinish_reason: choice.finish_reason as any,\n\t\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\t\tprovider: \"openai\",\n\t\t\t\t\t\t\t\tmodel: openaiChunk.model,\n\t\t\t\t\t\t\t\tid: openaiChunk.id,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t\tyield streamChunk;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tmetadata: { provider: \"openai\" },\n\t\t};\n\t}\n\n\tconvertToolsToFunctions(tools: ConnectorTool[]): ChatCompletionTool[] {\n\t\tconst functions: ChatCompletionTool[] = [];\n\t\tfor (const tool of tools) {\n\t\t\tfunctions.push({\n\t\t\t\ttype: \"function\",\n\t\t\t\tfunction: {\n\t\t\t\t\tname: tool.toolName,\n\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\tparameters: tool.inputSchema,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t\treturn functions;\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../index.ts"],"sourcesContent":["import {\n\ttype AssistantToolCallTurn,\n\tBaseModel,\n\ttype ModelFetchOptions,\n\ttype ToolResultMessage,\n} from \"@ainetwork/adk/modules\";\nimport type {\n\tConnectorTool,\n\tFetchResponse,\n\tToolCall,\n} from \"@ainetwork/adk/types/connector\";\nimport {\n\ttype MessageObject,\n\tMessageRole,\n\ttype ThreadObject,\n} from \"@ainetwork/adk/types/memory\";\nimport type {\n\tLLMStream,\n\tStreamChunk,\n\tToolCallDelta,\n} from \"@ainetwork/adk/types/stream\";\nimport { loggers } from \"@ainetwork/adk/utils/logger\";\nimport { AzureOpenAI as AzureOpenAIClient } from \"openai\";\nimport type {\n\tChatCompletionMessageParam as CCMessageParam,\n\tChatCompletionChunk,\n\tChatCompletionMessageFunctionToolCall,\n\tChatCompletionMessageToolCall,\n\tChatCompletionTool,\n} from \"openai/resources\";\n\nconst DEFAULT_TIMEOUT_MS = 120_000;\nconst DEFAULT_MAX_RETRIES = 1;\nconst PROVIDER = \"azure-openai\";\n\nexport interface AzureOpenAIConfig {\n\tendpoint?: string;\n\tdeployment?: string;\n\tbaseUrl?: string;\n\tapiKey: string;\n\tapiVersion: string;\n\tmodelName: string;\n\t/** Request timeout in milliseconds. Defaults to 120000 (2 minutes). */\n\ttimeout?: number;\n\t/** Maximum number of automatic retries. Defaults to 1. */\n\tmaxRetries?: number;\n}\n\nexport class AzureOpenAI extends BaseModel<CCMessageParam, ChatCompletionTool> {\n\tprivate client: AzureOpenAIClient;\n\tprivate modelName: string;\n\n\tconstructor({\n\t\tendpoint,\n\t\tdeployment,\n\t\tbaseUrl,\n\t\tapiKey,\n\t\tapiVersion,\n\t\tmodelName,\n\t\ttimeout = DEFAULT_TIMEOUT_MS,\n\t\tmaxRetries = DEFAULT_MAX_RETRIES,\n\t}: AzureOpenAIConfig) {\n\t\tsuper();\n\t\tconst options = {\n\t\t\tendpoint,\n\t\t\tapiKey,\n\t\t\tdeployment,\n\t\t\tapiVersion,\n\t\t\tbaseURL: baseUrl,\n\t\t\ttimeout,\n\t\t\tmaxRetries,\n\t\t};\n\t\tthis.client = new AzureOpenAIClient(options);\n\t\tthis.modelName = modelName;\n\t}\n\n\tprivate getMessageRole(role: MessageRole) {\n\t\tswitch (role) {\n\t\t\tcase MessageRole.USER:\n\t\t\t\treturn \"user\";\n\t\t\tcase MessageRole.MODEL:\n\t\t\t\treturn \"assistant\";\n\t\t\tcase MessageRole.SYSTEM:\n\t\t\t\treturn \"system\";\n\t\t\tdefault:\n\t\t\t\treturn \"system\";\n\t\t}\n\t}\n\n\tprivate logCallStart(method: string, messageCount: number, toolCount = 0) {\n\t\tloggers.model.debug(`[${PROVIDER}] ${method} start`, {\n\t\t\tprovider: PROVIDER,\n\t\t\tmodel: this.modelName,\n\t\t\tmessageCount,\n\t\t\ttoolCount,\n\t\t});\n\t}\n\n\tprivate logCallSuccess(method: string, startedAt: number) {\n\t\tloggers.model.info(`[${PROVIDER}] ${method} complete`, {\n\t\t\tprovider: PROVIDER,\n\t\t\tmodel: this.modelName,\n\t\t\tdurationMs: Date.now() - startedAt,\n\t\t});\n\t}\n\n\tprivate logCallFailure(method: string, startedAt: number, error: unknown) {\n\t\tloggers.model.error(`[${PROVIDER}] ${method} failed`, {\n\t\t\tprovider: PROVIDER,\n\t\t\tmodel: this.modelName,\n\t\t\tdurationMs: Date.now() - startedAt,\n\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t});\n\t}\n\n\tgenerateMessages(params: {\n\t\tquery: string;\n\t\tthread?: ThreadObject;\n\t\tsystemPrompt?: string;\n\t}): CCMessageParam[] {\n\t\tconst { query, thread, systemPrompt } = params;\n\t\tconst messages: CCMessageParam[] = !systemPrompt\n\t\t\t? []\n\t\t\t: [{ role: \"system\", content: systemPrompt.trim() }];\n\t\tconst sessionContent: CCMessageParam[] = !thread\n\t\t\t? []\n\t\t\t: thread.messages.map((message: MessageObject) => {\n\t\t\t\t\t// Prefer the real query stashed in metadata when a display text was\n\t\t\t\t\t// shown in its place (displayQuery), so multi-turn history carries\n\t\t\t\t\t// the actual query the model saw on the first turn — not the short\n\t\t\t\t\t// label. Falls back to the stored content otherwise.\n\t\t\t\t\tconst content =\n\t\t\t\t\t\ttypeof message.metadata?.query === \"string\"\n\t\t\t\t\t\t\t? message.metadata.query\n\t\t\t\t\t\t\t: (message.content.parts[0] as string);\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: this.getMessageRole(message.role),\n\t\t\t\t\t\tcontent,\n\t\t\t\t\t};\n\t\t\t\t});\n\t\tconst userContent: CCMessageParam = { role: \"user\", content: query };\n\t\treturn messages.concat(sessionContent).concat(userContent);\n\t}\n\n\tappendAssistantToolCallTurn(\n\t\tmessages: CCMessageParam[],\n\t\tturn: AssistantToolCallTurn,\n\t): void {\n\t\tmessages.push({\n\t\t\trole: \"assistant\",\n\t\t\tcontent: turn.content,\n\t\t\ttool_calls: turn.toolCalls.map(\n\t\t\t\t(tc): ChatCompletionMessageFunctionToolCall => ({\n\t\t\t\t\tid: tc.id,\n\t\t\t\t\ttype: \"function\",\n\t\t\t\t\tfunction: {\n\t\t\t\t\t\tname: tc.function.name,\n\t\t\t\t\t\targuments: tc.function.arguments,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t),\n\t\t});\n\t}\n\n\tappendToolResult(\n\t\tmessages: CCMessageParam[],\n\t\tresult: ToolResultMessage,\n\t): void {\n\t\tmessages.push({\n\t\t\trole: \"tool\",\n\t\t\ttool_call_id: result.toolCallId,\n\t\t\tcontent: result.content,\n\t\t});\n\t}\n\n\tasync fetch(\n\t\tmessages: CCMessageParam[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<FetchResponse> {\n\t\tconst startedAt = Date.now();\n\t\tthis.logCallStart(\"fetch\", messages.length);\n\t\ttry {\n\t\t\tconst response = await this.client.chat.completions.create({\n\t\t\t\tmodel: this.modelName,\n\t\t\t\tmessages,\n\t\t\t\treasoning_effort: options?.reasoning,\n\t\t\t\tverbosity: options?.verbosity,\n\t\t\t});\n\t\t\tthis.logCallSuccess(\"fetch\", startedAt);\n\n\t\t\treturn {\n\t\t\t\tcontent: response.choices[0].message.content || undefined,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthis.logCallFailure(\"fetch\", startedAt, error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync fetchWithContextMessage(\n\t\tmessages: CCMessageParam[],\n\t\tfunctions: ChatCompletionTool[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<FetchResponse> {\n\t\tif (functions.length > 0) {\n\t\t\tconst startedAt = Date.now();\n\t\t\tthis.logCallStart(\n\t\t\t\t\"fetchWithContextMessage\",\n\t\t\t\tmessages.length,\n\t\t\t\tfunctions.length,\n\t\t\t);\n\t\t\ttry {\n\t\t\t\tconst response = await this.client.chat.completions.create({\n\t\t\t\t\tmodel: this.modelName,\n\t\t\t\t\tmessages,\n\t\t\t\t\ttools: functions,\n\t\t\t\t\ttool_choice: options?.toolChoice ?? \"auto\",\n\t\t\t\t\treasoning_effort: options?.reasoning,\n\t\t\t\t\tverbosity: options?.verbosity,\n\t\t\t\t});\n\t\t\t\tthis.logCallSuccess(\"fetchWithContextMessage\", startedAt);\n\n\t\t\t\tconst { content, tool_calls } = response.choices[0].message;\n\n\t\t\t\tconst toolCalls: ToolCall[] | undefined = tool_calls?.map(\n\t\t\t\t\t(value: ChatCompletionMessageToolCall) => {\n\t\t\t\t\t\tconst v = value as ChatCompletionMessageFunctionToolCall;\n\t\t\t\t\t\tlet args: Record<string, unknown>;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\targs = JSON.parse(v.function.arguments);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// Forward the raw argument string so the caller can surface it\n\t\t\t\t\t\t\t// (and the model can self-correct) instead of killing the fetch.\n\t\t\t\t\t\t\targs = { __raw: v.function.arguments };\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tname: v.function.name,\n\t\t\t\t\t\t\targuments: args,\n\t\t\t\t\t\t};\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\treturn {\n\t\t\t\t\tcontent: content || undefined,\n\t\t\t\t\ttoolCalls,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tthis.logCallFailure(\"fetchWithContextMessage\", startedAt, error);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\treturn await this.fetch(messages, options);\n\t}\n\n\tasync fetchStreamWithContextMessage(\n\t\tmessages: CCMessageParam[],\n\t\tfunctions: ChatCompletionTool[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<LLMStream> {\n\t\tconst startedAt = Date.now();\n\t\tthis.logCallStart(\n\t\t\t\"fetchStreamWithContextMessage\",\n\t\t\tmessages.length,\n\t\t\tfunctions.length,\n\t\t);\n\t\ttry {\n\t\t\tconst stream = await this.client.chat.completions.create({\n\t\t\t\tmodel: this.modelName,\n\t\t\t\tmessages,\n\t\t\t\t...(functions.length > 0\n\t\t\t\t\t? {\n\t\t\t\t\t\t\ttools: functions,\n\t\t\t\t\t\t\ttool_choice: options?.toolChoice ?? \"auto\",\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t\tstream: true,\n\t\t\t\treasoning_effort: options?.reasoning,\n\t\t\t\tverbosity: options?.verbosity,\n\t\t\t});\n\t\t\treturn this.withStreamLogging(\n\t\t\t\tthis.createOpenAIStreamAdapter(stream),\n\t\t\t\t\"fetchStreamWithContextMessage\",\n\t\t\t\tstartedAt,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthis.logCallFailure(\"fetchStreamWithContextMessage\", startedAt, error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Wraps an LLMStream so the completion log covers the whole stream\n\t * lifetime, not just the initial request.\n\t */\n\tprivate withStreamLogging(\n\t\tstream: LLMStream,\n\t\tmethod: string,\n\t\tstartedAt: number,\n\t): LLMStream {\n\t\tconst logSuccess = () => this.logCallSuccess(method, startedAt);\n\t\tconst logFailure = (error: unknown) =>\n\t\t\tthis.logCallFailure(method, startedAt, error);\n\t\treturn {\n\t\t\t...stream,\n\t\t\tasync *[Symbol.asyncIterator](): AsyncIterator<StreamChunk> {\n\t\t\t\ttry {\n\t\t\t\t\tyield* stream;\n\t\t\t\t\tlogSuccess();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlogFailure(error);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t}\n\n\t// NOTE(yoojin): Need to switch API Stream type to LLMStream.\n\tprivate createOpenAIStreamAdapter(\n\t\topenaiStream: AsyncIterable<ChatCompletionChunk>,\n\t): LLMStream {\n\t\treturn {\n\t\t\tasync *[Symbol.asyncIterator](): AsyncIterator<StreamChunk> {\n\t\t\t\tfor await (const openaiChunk of openaiStream) {\n\t\t\t\t\tconst choice = openaiChunk.choices[0];\n\t\t\t\t\tif (choice) {\n\t\t\t\t\t\tconst streamChunk: StreamChunk = {\n\t\t\t\t\t\t\tdelta: {\n\t\t\t\t\t\t\t\trole: choice.delta?.role || undefined,\n\t\t\t\t\t\t\t\tcontent: choice.delta?.content || undefined,\n\t\t\t\t\t\t\t\ttool_calls: choice.delta?.tool_calls?.map(\n\t\t\t\t\t\t\t\t\t(tc) =>\n\t\t\t\t\t\t\t\t\t\t({\n\t\t\t\t\t\t\t\t\t\t\tindex: tc.index,\n\t\t\t\t\t\t\t\t\t\t\tid: tc.id,\n\t\t\t\t\t\t\t\t\t\t\ttype: tc.type,\n\t\t\t\t\t\t\t\t\t\t\tfunction: tc.function,\n\t\t\t\t\t\t\t\t\t\t}) as ToolCallDelta,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tfinish_reason: choice.finish_reason as any,\n\t\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\t\tprovider: \"openai\",\n\t\t\t\t\t\t\t\tmodel: openaiChunk.model,\n\t\t\t\t\t\t\t\tid: openaiChunk.id,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t\tyield streamChunk;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tmetadata: { provider: \"openai\" },\n\t\t};\n\t}\n\n\tconvertToolsToFunctions(tools: ConnectorTool[]): ChatCompletionTool[] {\n\t\tconst functions: ChatCompletionTool[] = [];\n\t\tfor (const tool of tools) {\n\t\t\tfunctions.push({\n\t\t\t\ttype: \"function\",\n\t\t\t\tfunction: {\n\t\t\t\t\tname: tool.toolName,\n\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\tparameters: tool.inputSchema,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t\treturn functions;\n\t}\n}\n"],"mappings":"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","names":[]}
|
package/index.ts
CHANGED
|
@@ -19,6 +19,7 @@ import type {
|
|
|
19
19
|
StreamChunk,
|
|
20
20
|
ToolCallDelta,
|
|
21
21
|
} from "@ainetwork/adk/types/stream";
|
|
22
|
+
import { loggers } from "@ainetwork/adk/utils/logger";
|
|
22
23
|
import { AzureOpenAI as AzureOpenAIClient } from "openai";
|
|
23
24
|
import type {
|
|
24
25
|
ChatCompletionMessageParam as CCMessageParam,
|
|
@@ -28,6 +29,10 @@ import type {
|
|
|
28
29
|
ChatCompletionTool,
|
|
29
30
|
} from "openai/resources";
|
|
30
31
|
|
|
32
|
+
const DEFAULT_TIMEOUT_MS = 120_000;
|
|
33
|
+
const DEFAULT_MAX_RETRIES = 1;
|
|
34
|
+
const PROVIDER = "azure-openai";
|
|
35
|
+
|
|
31
36
|
export interface AzureOpenAIConfig {
|
|
32
37
|
endpoint?: string;
|
|
33
38
|
deployment?: string;
|
|
@@ -35,6 +40,10 @@ export interface AzureOpenAIConfig {
|
|
|
35
40
|
apiKey: string;
|
|
36
41
|
apiVersion: string;
|
|
37
42
|
modelName: string;
|
|
43
|
+
/** Request timeout in milliseconds. Defaults to 120000 (2 minutes). */
|
|
44
|
+
timeout?: number;
|
|
45
|
+
/** Maximum number of automatic retries. Defaults to 1. */
|
|
46
|
+
maxRetries?: number;
|
|
38
47
|
}
|
|
39
48
|
|
|
40
49
|
export class AzureOpenAI extends BaseModel<CCMessageParam, ChatCompletionTool> {
|
|
@@ -48,6 +57,8 @@ export class AzureOpenAI extends BaseModel<CCMessageParam, ChatCompletionTool> {
|
|
|
48
57
|
apiKey,
|
|
49
58
|
apiVersion,
|
|
50
59
|
modelName,
|
|
60
|
+
timeout = DEFAULT_TIMEOUT_MS,
|
|
61
|
+
maxRetries = DEFAULT_MAX_RETRIES,
|
|
51
62
|
}: AzureOpenAIConfig) {
|
|
52
63
|
super();
|
|
53
64
|
const options = {
|
|
@@ -56,6 +67,8 @@ export class AzureOpenAI extends BaseModel<CCMessageParam, ChatCompletionTool> {
|
|
|
56
67
|
deployment,
|
|
57
68
|
apiVersion,
|
|
58
69
|
baseURL: baseUrl,
|
|
70
|
+
timeout,
|
|
71
|
+
maxRetries,
|
|
59
72
|
};
|
|
60
73
|
this.client = new AzureOpenAIClient(options);
|
|
61
74
|
this.modelName = modelName;
|
|
@@ -66,13 +79,40 @@ export class AzureOpenAI extends BaseModel<CCMessageParam, ChatCompletionTool> {
|
|
|
66
79
|
case MessageRole.USER:
|
|
67
80
|
return "user";
|
|
68
81
|
case MessageRole.MODEL:
|
|
82
|
+
return "assistant";
|
|
69
83
|
case MessageRole.SYSTEM:
|
|
70
84
|
return "system";
|
|
71
85
|
default:
|
|
72
|
-
return "system";
|
|
86
|
+
return "system";
|
|
73
87
|
}
|
|
74
88
|
}
|
|
75
89
|
|
|
90
|
+
private logCallStart(method: string, messageCount: number, toolCount = 0) {
|
|
91
|
+
loggers.model.debug(`[${PROVIDER}] ${method} start`, {
|
|
92
|
+
provider: PROVIDER,
|
|
93
|
+
model: this.modelName,
|
|
94
|
+
messageCount,
|
|
95
|
+
toolCount,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private logCallSuccess(method: string, startedAt: number) {
|
|
100
|
+
loggers.model.info(`[${PROVIDER}] ${method} complete`, {
|
|
101
|
+
provider: PROVIDER,
|
|
102
|
+
model: this.modelName,
|
|
103
|
+
durationMs: Date.now() - startedAt,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
private logCallFailure(method: string, startedAt: number, error: unknown) {
|
|
108
|
+
loggers.model.error(`[${PROVIDER}] ${method} failed`, {
|
|
109
|
+
provider: PROVIDER,
|
|
110
|
+
model: this.modelName,
|
|
111
|
+
durationMs: Date.now() - startedAt,
|
|
112
|
+
error: error instanceof Error ? error.message : String(error),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
76
116
|
generateMessages(params: {
|
|
77
117
|
query: string;
|
|
78
118
|
thread?: ThreadObject;
|
|
@@ -137,16 +177,24 @@ export class AzureOpenAI extends BaseModel<CCMessageParam, ChatCompletionTool> {
|
|
|
137
177
|
messages: CCMessageParam[],
|
|
138
178
|
options?: ModelFetchOptions,
|
|
139
179
|
): Promise<FetchResponse> {
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
180
|
+
const startedAt = Date.now();
|
|
181
|
+
this.logCallStart("fetch", messages.length);
|
|
182
|
+
try {
|
|
183
|
+
const response = await this.client.chat.completions.create({
|
|
184
|
+
model: this.modelName,
|
|
185
|
+
messages,
|
|
186
|
+
reasoning_effort: options?.reasoning,
|
|
187
|
+
verbosity: options?.verbosity,
|
|
188
|
+
});
|
|
189
|
+
this.logCallSuccess("fetch", startedAt);
|
|
146
190
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
191
|
+
return {
|
|
192
|
+
content: response.choices[0].message.content || undefined,
|
|
193
|
+
};
|
|
194
|
+
} catch (error) {
|
|
195
|
+
this.logCallFailure("fetch", startedAt, error);
|
|
196
|
+
throw error;
|
|
197
|
+
}
|
|
150
198
|
}
|
|
151
199
|
|
|
152
200
|
async fetchWithContextMessage(
|
|
@@ -155,34 +203,53 @@ export class AzureOpenAI extends BaseModel<CCMessageParam, ChatCompletionTool> {
|
|
|
155
203
|
options?: ModelFetchOptions,
|
|
156
204
|
): Promise<FetchResponse> {
|
|
157
205
|
if (functions.length > 0) {
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
206
|
+
const startedAt = Date.now();
|
|
207
|
+
this.logCallStart(
|
|
208
|
+
"fetchWithContextMessage",
|
|
209
|
+
messages.length,
|
|
210
|
+
functions.length,
|
|
211
|
+
);
|
|
212
|
+
try {
|
|
213
|
+
const response = await this.client.chat.completions.create({
|
|
214
|
+
model: this.modelName,
|
|
215
|
+
messages,
|
|
216
|
+
tools: functions,
|
|
217
|
+
tool_choice: options?.toolChoice ?? "auto",
|
|
218
|
+
reasoning_effort: options?.reasoning,
|
|
219
|
+
verbosity: options?.verbosity,
|
|
220
|
+
});
|
|
221
|
+
this.logCallSuccess("fetchWithContextMessage", startedAt);
|
|
166
222
|
|
|
167
|
-
|
|
223
|
+
const { content, tool_calls } = response.choices[0].message;
|
|
168
224
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
225
|
+
const toolCalls: ToolCall[] | undefined = tool_calls?.map(
|
|
226
|
+
(value: ChatCompletionMessageToolCall) => {
|
|
227
|
+
const v = value as ChatCompletionMessageFunctionToolCall;
|
|
228
|
+
let args: Record<string, unknown>;
|
|
229
|
+
try {
|
|
230
|
+
args = JSON.parse(v.function.arguments);
|
|
231
|
+
} catch {
|
|
232
|
+
// Forward the raw argument string so the caller can surface it
|
|
233
|
+
// (and the model can self-correct) instead of killing the fetch.
|
|
234
|
+
args = { __raw: v.function.arguments };
|
|
235
|
+
}
|
|
236
|
+
return {
|
|
237
|
+
name: v.function.name,
|
|
238
|
+
arguments: args,
|
|
239
|
+
};
|
|
240
|
+
},
|
|
241
|
+
);
|
|
179
242
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
243
|
+
return {
|
|
244
|
+
content: content || undefined,
|
|
245
|
+
toolCalls,
|
|
246
|
+
};
|
|
247
|
+
} catch (error) {
|
|
248
|
+
this.logCallFailure("fetchWithContextMessage", startedAt, error);
|
|
249
|
+
throw error;
|
|
250
|
+
}
|
|
184
251
|
}
|
|
185
|
-
return await this.fetch(messages);
|
|
252
|
+
return await this.fetch(messages, options);
|
|
186
253
|
}
|
|
187
254
|
|
|
188
255
|
async fetchStreamWithContextMessage(
|
|
@@ -190,17 +257,61 @@ export class AzureOpenAI extends BaseModel<CCMessageParam, ChatCompletionTool> {
|
|
|
190
257
|
functions: ChatCompletionTool[],
|
|
191
258
|
options?: ModelFetchOptions,
|
|
192
259
|
): Promise<LLMStream> {
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
260
|
+
const startedAt = Date.now();
|
|
261
|
+
this.logCallStart(
|
|
262
|
+
"fetchStreamWithContextMessage",
|
|
263
|
+
messages.length,
|
|
264
|
+
functions.length,
|
|
265
|
+
);
|
|
266
|
+
try {
|
|
267
|
+
const stream = await this.client.chat.completions.create({
|
|
268
|
+
model: this.modelName,
|
|
269
|
+
messages,
|
|
270
|
+
...(functions.length > 0
|
|
271
|
+
? {
|
|
272
|
+
tools: functions,
|
|
273
|
+
tool_choice: options?.toolChoice ?? "auto",
|
|
274
|
+
}
|
|
275
|
+
: {}),
|
|
276
|
+
stream: true,
|
|
277
|
+
reasoning_effort: options?.reasoning,
|
|
278
|
+
verbosity: options?.verbosity,
|
|
279
|
+
});
|
|
280
|
+
return this.withStreamLogging(
|
|
281
|
+
this.createOpenAIStreamAdapter(stream),
|
|
282
|
+
"fetchStreamWithContextMessage",
|
|
283
|
+
startedAt,
|
|
284
|
+
);
|
|
285
|
+
} catch (error) {
|
|
286
|
+
this.logCallFailure("fetchStreamWithContextMessage", startedAt, error);
|
|
287
|
+
throw error;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Wraps an LLMStream so the completion log covers the whole stream
|
|
293
|
+
* lifetime, not just the initial request.
|
|
294
|
+
*/
|
|
295
|
+
private withStreamLogging(
|
|
296
|
+
stream: LLMStream,
|
|
297
|
+
method: string,
|
|
298
|
+
startedAt: number,
|
|
299
|
+
): LLMStream {
|
|
300
|
+
const logSuccess = () => this.logCallSuccess(method, startedAt);
|
|
301
|
+
const logFailure = (error: unknown) =>
|
|
302
|
+
this.logCallFailure(method, startedAt, error);
|
|
303
|
+
return {
|
|
304
|
+
...stream,
|
|
305
|
+
async *[Symbol.asyncIterator](): AsyncIterator<StreamChunk> {
|
|
306
|
+
try {
|
|
307
|
+
yield* stream;
|
|
308
|
+
logSuccess();
|
|
309
|
+
} catch (error) {
|
|
310
|
+
logFailure(error);
|
|
311
|
+
throw error;
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
};
|
|
204
315
|
}
|
|
205
316
|
|
|
206
317
|
// NOTE(yoojin): Need to switch API Stream type to LLMStream.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainetwork/adk-provider-model-azure",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"author": "AI Network (https://ainetwork.ai)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"openai": "^6.9.1"
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
|
-
"@ainetwork/adk": "^0.8.
|
|
27
|
+
"@ainetwork/adk": "^0.8.2"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"typescript": "^5.0.0"
|
|
@@ -33,5 +33,5 @@
|
|
|
33
33
|
"publishConfig": {
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "abcf4759a1c143abcacc59dfbf2f1b8aa0f9f17b"
|
|
37
37
|
}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { loggers } from "@ainetwork/adk/utils/logger";
|
|
2
|
+
import type { ChatCompletionMessageParam } from "openai/resources";
|
|
3
|
+
import { AzureOpenAI } from "../index";
|
|
4
|
+
|
|
5
|
+
const mockCreate = jest.fn();
|
|
6
|
+
|
|
7
|
+
jest.mock("openai", () => ({
|
|
8
|
+
AzureOpenAI: jest.fn().mockImplementation(() => ({
|
|
9
|
+
chat: { completions: { create: mockCreate } },
|
|
10
|
+
})),
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
const MockedClient = jest.requireMock("openai").AzureOpenAI as jest.Mock;
|
|
14
|
+
|
|
15
|
+
function makeProvider(extra?: {
|
|
16
|
+
timeout?: number;
|
|
17
|
+
maxRetries?: number;
|
|
18
|
+
}): AzureOpenAI {
|
|
19
|
+
return new AzureOpenAI({
|
|
20
|
+
endpoint: "https://example.azure.test",
|
|
21
|
+
apiKey: "test-key",
|
|
22
|
+
apiVersion: "2024-10-21",
|
|
23
|
+
modelName: "gpt-test",
|
|
24
|
+
...extra,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function textResponse(content: string | null) {
|
|
29
|
+
return { choices: [{ message: { content } }] };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function* fakeStream() {
|
|
33
|
+
yield {
|
|
34
|
+
id: "c1",
|
|
35
|
+
model: "gpt-test",
|
|
36
|
+
choices: [
|
|
37
|
+
{ delta: { role: "assistant", content: "hi" }, finish_reason: null },
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
yield {
|
|
41
|
+
id: "c1",
|
|
42
|
+
model: "gpt-test",
|
|
43
|
+
choices: [{ delta: {}, finish_reason: "stop" }],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const userMessages: ChatCompletionMessageParam[] = [
|
|
48
|
+
{ role: "user", content: "hello" },
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
beforeEach(() => {
|
|
52
|
+
mockCreate.mockReset();
|
|
53
|
+
MockedClient.mockClear();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
describe("AzureOpenAI client configuration", () => {
|
|
57
|
+
it("passes default timeout (120000ms) and maxRetries (1) to the client", () => {
|
|
58
|
+
makeProvider();
|
|
59
|
+
expect(MockedClient).toHaveBeenCalledWith(
|
|
60
|
+
expect.objectContaining({ timeout: 120_000, maxRetries: 1 }),
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("honors configured timeout and maxRetries", () => {
|
|
65
|
+
makeProvider({ timeout: 5_000, maxRetries: 3 });
|
|
66
|
+
expect(MockedClient).toHaveBeenCalledWith(
|
|
67
|
+
expect.objectContaining({ timeout: 5_000, maxRetries: 3 }),
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
describe("AzureOpenAI empty-tools guard", () => {
|
|
73
|
+
it("omits tools/tool_choice on the non-streaming path when functions are empty", async () => {
|
|
74
|
+
mockCreate.mockResolvedValue(textResponse("ok"));
|
|
75
|
+
const provider = makeProvider();
|
|
76
|
+
|
|
77
|
+
await provider.fetchWithContextMessage(userMessages, []);
|
|
78
|
+
|
|
79
|
+
expect(mockCreate).toHaveBeenCalledTimes(1);
|
|
80
|
+
const payload = mockCreate.mock.calls[0][0];
|
|
81
|
+
expect(payload).not.toHaveProperty("tools");
|
|
82
|
+
expect(payload).not.toHaveProperty("tool_choice");
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("omits tools/tool_choice on the streaming path when functions are empty", async () => {
|
|
86
|
+
mockCreate.mockResolvedValue(fakeStream());
|
|
87
|
+
const provider = makeProvider();
|
|
88
|
+
|
|
89
|
+
await provider.fetchStreamWithContextMessage(userMessages, []);
|
|
90
|
+
|
|
91
|
+
const payload = mockCreate.mock.calls[0][0];
|
|
92
|
+
expect(payload).not.toHaveProperty("tools");
|
|
93
|
+
expect(payload).not.toHaveProperty("tool_choice");
|
|
94
|
+
expect(payload.stream).toBe(true);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("still sends tools/tool_choice on the streaming path when functions exist", async () => {
|
|
98
|
+
mockCreate.mockResolvedValue(fakeStream());
|
|
99
|
+
const provider = makeProvider();
|
|
100
|
+
const tools = provider.convertToolsToFunctions([
|
|
101
|
+
{ toolName: "t1", description: "d", inputSchema: { type: "object" } },
|
|
102
|
+
// biome-ignore lint/suspicious/noExplicitAny: minimal test fixture
|
|
103
|
+
] as any);
|
|
104
|
+
|
|
105
|
+
await provider.fetchStreamWithContextMessage(userMessages, tools);
|
|
106
|
+
|
|
107
|
+
const payload = mockCreate.mock.calls[0][0];
|
|
108
|
+
expect(payload.tools).toHaveLength(1);
|
|
109
|
+
expect(payload.tool_choice).toBe("auto");
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
describe("AzureOpenAI tool-call argument parsing", () => {
|
|
114
|
+
it("forwards malformed tool-call JSON as {__raw} instead of throwing", async () => {
|
|
115
|
+
mockCreate.mockResolvedValue({
|
|
116
|
+
choices: [
|
|
117
|
+
{
|
|
118
|
+
message: {
|
|
119
|
+
content: null,
|
|
120
|
+
tool_calls: [
|
|
121
|
+
{
|
|
122
|
+
id: "call_1",
|
|
123
|
+
type: "function",
|
|
124
|
+
function: { name: "search", arguments: "{not json" },
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
});
|
|
131
|
+
const provider = makeProvider();
|
|
132
|
+
const tools = provider.convertToolsToFunctions([
|
|
133
|
+
{ toolName: "search", description: "d", inputSchema: { type: "object" } },
|
|
134
|
+
// biome-ignore lint/suspicious/noExplicitAny: minimal test fixture
|
|
135
|
+
] as any);
|
|
136
|
+
|
|
137
|
+
const result = await provider.fetchWithContextMessage(userMessages, tools);
|
|
138
|
+
|
|
139
|
+
expect(result.toolCalls).toEqual([
|
|
140
|
+
{ name: "search", arguments: { __raw: "{not json" } },
|
|
141
|
+
]);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
describe("AzureOpenAI options forwarding", () => {
|
|
146
|
+
it("forwards ModelFetchOptions when falling back to fetch on empty functions", async () => {
|
|
147
|
+
mockCreate.mockResolvedValue(textResponse("ok"));
|
|
148
|
+
const provider = makeProvider();
|
|
149
|
+
|
|
150
|
+
await provider.fetchWithContextMessage(userMessages, [], {
|
|
151
|
+
reasoning: "low",
|
|
152
|
+
verbosity: "high",
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
const payload = mockCreate.mock.calls[0][0];
|
|
156
|
+
expect(payload.reasoning_effort).toBe("low");
|
|
157
|
+
expect(payload.verbosity).toBe("high");
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
describe("AzureOpenAI role mapping", () => {
|
|
162
|
+
it("maps MODEL history messages to role 'assistant'", () => {
|
|
163
|
+
const provider = makeProvider();
|
|
164
|
+
const messages = provider.generateMessages({
|
|
165
|
+
query: "next",
|
|
166
|
+
thread: {
|
|
167
|
+
messages: [
|
|
168
|
+
{
|
|
169
|
+
messageId: "m1",
|
|
170
|
+
role: "MODEL",
|
|
171
|
+
timestamp: 1,
|
|
172
|
+
content: { type: "text", parts: ["previous answer"] },
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
// biome-ignore lint/suspicious/noExplicitAny: minimal test fixture
|
|
176
|
+
} as any,
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
const history = messages.find((m) => m.content === "previous answer");
|
|
180
|
+
expect(history?.role).toBe("assistant");
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
describe("AzureOpenAI model-call logging", () => {
|
|
185
|
+
let debugSpy: jest.SpyInstance;
|
|
186
|
+
let infoSpy: jest.SpyInstance;
|
|
187
|
+
let errorSpy: jest.SpyInstance;
|
|
188
|
+
|
|
189
|
+
beforeEach(() => {
|
|
190
|
+
debugSpy = jest.spyOn(loggers.model, "debug").mockImplementation();
|
|
191
|
+
infoSpy = jest.spyOn(loggers.model, "info").mockImplementation();
|
|
192
|
+
errorSpy = jest.spyOn(loggers.model, "error").mockImplementation();
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
afterEach(() => {
|
|
196
|
+
debugSpy.mockRestore();
|
|
197
|
+
infoSpy.mockRestore();
|
|
198
|
+
errorSpy.mockRestore();
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it("logs start (debug) and completion (info with durationMs) on fetch", async () => {
|
|
202
|
+
mockCreate.mockResolvedValue(textResponse("ok"));
|
|
203
|
+
const provider = makeProvider();
|
|
204
|
+
|
|
205
|
+
await provider.fetch(userMessages);
|
|
206
|
+
|
|
207
|
+
expect(debugSpy).toHaveBeenCalledWith(
|
|
208
|
+
expect.stringContaining("fetch"),
|
|
209
|
+
expect.objectContaining({
|
|
210
|
+
provider: "azure-openai",
|
|
211
|
+
model: "gpt-test",
|
|
212
|
+
messageCount: 1,
|
|
213
|
+
}),
|
|
214
|
+
);
|
|
215
|
+
expect(infoSpy).toHaveBeenCalledWith(
|
|
216
|
+
expect.stringContaining("fetch"),
|
|
217
|
+
expect.objectContaining({ durationMs: expect.any(Number) }),
|
|
218
|
+
);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it("never logs message contents or the apiKey", async () => {
|
|
222
|
+
mockCreate.mockResolvedValue(textResponse("ok"));
|
|
223
|
+
const provider = makeProvider();
|
|
224
|
+
|
|
225
|
+
await provider.fetch([{ role: "user", content: "SECRET-CONTENT" }]);
|
|
226
|
+
|
|
227
|
+
const allMeta = JSON.stringify([
|
|
228
|
+
...debugSpy.mock.calls,
|
|
229
|
+
...infoSpy.mock.calls,
|
|
230
|
+
]);
|
|
231
|
+
expect(allMeta).not.toContain("SECRET-CONTENT");
|
|
232
|
+
expect(allMeta).not.toContain("test-key");
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it("logs an error with the failure message and rethrows", async () => {
|
|
236
|
+
mockCreate.mockRejectedValue(new Error("boom"));
|
|
237
|
+
const provider = makeProvider();
|
|
238
|
+
|
|
239
|
+
await expect(provider.fetch(userMessages)).rejects.toThrow("boom");
|
|
240
|
+
expect(errorSpy).toHaveBeenCalledWith(
|
|
241
|
+
expect.any(String),
|
|
242
|
+
expect.objectContaining({ error: "boom" }),
|
|
243
|
+
);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it("logs stream completion only after the stream is fully consumed", async () => {
|
|
247
|
+
mockCreate.mockResolvedValue(fakeStream());
|
|
248
|
+
const provider = makeProvider();
|
|
249
|
+
|
|
250
|
+
const stream = await provider.fetchStreamWithContextMessage(
|
|
251
|
+
userMessages,
|
|
252
|
+
[],
|
|
253
|
+
);
|
|
254
|
+
expect(infoSpy).not.toHaveBeenCalled();
|
|
255
|
+
|
|
256
|
+
for await (const _chunk of stream) {
|
|
257
|
+
// drain
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
expect(infoSpy).toHaveBeenCalledWith(
|
|
261
|
+
expect.any(String),
|
|
262
|
+
expect.objectContaining({ durationMs: expect.any(Number) }),
|
|
263
|
+
);
|
|
264
|
+
});
|
|
265
|
+
});
|
package/tsup.config.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { defineConfig } from
|
|
1
|
+
import { defineConfig } from "tsup";
|
|
2
2
|
|
|
3
3
|
export default defineConfig({
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
})
|
|
4
|
+
entry: ["index.ts"],
|
|
5
|
+
format: ["cjs", "esm"],
|
|
6
|
+
dts: true,
|
|
7
|
+
sourcemap: true,
|
|
8
|
+
clean: true,
|
|
9
|
+
});
|