@mozaik-ai/core 0.9.4 → 2.0.1
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/README.md +51 -214
- package/dist/index.d.mts +121 -105
- package/dist/index.d.ts +121 -105
- package/dist/index.js +175 -1073
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +167 -1058
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,1160 +15,264 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
|
|
30
20
|
// src/index.ts
|
|
31
21
|
var index_exports = {};
|
|
32
22
|
__export(index_exports, {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
23
|
+
Context: () => Context,
|
|
24
|
+
ContextItem: () => ContextItem,
|
|
25
|
+
DeveloperMessage: () => DeveloperMessage,
|
|
26
|
+
FunctionCall: () => FunctionCall,
|
|
27
|
+
FunctionCallOutput: () => FunctionCallOutput,
|
|
28
|
+
GenerativeModel: () => GenerativeModel,
|
|
29
|
+
ModelMessage: () => ModelMessage,
|
|
30
|
+
Reasoning: () => Reasoning,
|
|
31
|
+
UserMessage: () => UserMessage
|
|
39
32
|
});
|
|
40
33
|
module.exports = __toCommonJS(index_exports);
|
|
41
34
|
|
|
42
|
-
// src/
|
|
43
|
-
var
|
|
44
|
-
constructor() {
|
|
35
|
+
// src/domain/context-runtime/context.ts
|
|
36
|
+
var Context = class _Context {
|
|
37
|
+
constructor(id, projectId, items) {
|
|
38
|
+
this.projectId = projectId;
|
|
39
|
+
this.id = id;
|
|
40
|
+
this.items = items;
|
|
45
41
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
// src/core/endpoint/request-gateway.ts
|
|
49
|
-
var RequestGateway = class {
|
|
50
|
-
constructor(endpointResolver) {
|
|
51
|
-
this.endpointResolver = endpointResolver;
|
|
52
|
-
}
|
|
53
|
-
async invoke(request) {
|
|
54
|
-
this.endpoint = this.endpointResolver.resolve(request.model);
|
|
55
|
-
return await this.endpoint.sendRequest(request);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// src/core/endpoint/endpoint-resolver.ts
|
|
60
|
-
var EndpointResolver = class {
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
// src/types/model.ts
|
|
64
|
-
var OPENAI_MODELS = ["gpt-5", "gpt-5-mini", "gpt-5-nano", "gpt-5.1", "gpt-5.2", "gpt-5.4"];
|
|
65
|
-
var latest_sonnet = "claude-sonnet-4-5-20250929";
|
|
66
|
-
var latest_haiku = "claude-haiku-4-5-20251001";
|
|
67
|
-
var latest_opus = "claude-opus-4-5-20251101";
|
|
68
|
-
var ANTHROPIC_MODELS = ["claude-sonnet-4.5", "claude-haiku-4.5", "claude-opus-4.5"];
|
|
69
|
-
var ANTHROPIC_MODEL_MAP = {
|
|
70
|
-
"claude-sonnet-4.5": latest_sonnet,
|
|
71
|
-
"claude-haiku-4.5": latest_haiku,
|
|
72
|
-
"claude-opus-4.5": latest_opus
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
// src/core/request-handler/capability.ts
|
|
76
|
-
var CapabilityHandler = class {
|
|
77
|
-
setNextHandler(capability) {
|
|
78
|
-
this.nextHandler = capability;
|
|
79
|
-
return this.nextHandler;
|
|
80
|
-
}
|
|
81
|
-
handle(request, builder) {
|
|
82
|
-
this.apply(request, builder);
|
|
83
|
-
if (this.nextHandler) {
|
|
84
|
-
this.nextHandler.handle(request, builder);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
// src/core/request-handler/messages.ts
|
|
90
|
-
var MessagesHandler = class extends CapabilityHandler {
|
|
91
|
-
apply(request, builder) {
|
|
92
|
-
if (request.messages) {
|
|
93
|
-
builder.addMessages(request.messages);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
// src/core/request-handler/task.ts
|
|
99
|
-
var TaskHandler = class extends CapabilityHandler {
|
|
100
|
-
apply(request, builder) {
|
|
101
|
-
if (request.task) {
|
|
102
|
-
builder.addTask(request.task);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
// src/core/request-handler/model.ts
|
|
108
|
-
var ModelHandler = class extends CapabilityHandler {
|
|
109
|
-
apply(request, builder) {
|
|
110
|
-
if (request.model) {
|
|
111
|
-
builder.addModel(request.model);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
// src/core/request-handler/structured-output.ts
|
|
117
|
-
var StructuredOutputlHandler = class extends CapabilityHandler {
|
|
118
|
-
apply(request, builder) {
|
|
119
|
-
if (request.structuredOutput) {
|
|
120
|
-
builder.addStructuredOutput(request.structuredOutput);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
// src/core/request-handler/tools.ts
|
|
126
|
-
var ToolsHandler = class extends CapabilityHandler {
|
|
127
|
-
apply(mozaikRequest, requestBuilder) {
|
|
128
|
-
if (mozaikRequest.tools && mozaikRequest.tools.length > 0) {
|
|
129
|
-
requestBuilder.addTools(mozaikRequest.tools);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
// src/core/endpoint/endpoint.ts
|
|
135
|
-
var Endpoint = class {
|
|
136
|
-
constructor() {
|
|
137
|
-
this.request = null;
|
|
138
|
-
}
|
|
139
|
-
buildRequest(request) {
|
|
140
|
-
this.request = request;
|
|
141
|
-
this.requestBuilder.initialize();
|
|
142
|
-
const messagesHandler = new MessagesHandler();
|
|
143
|
-
const taskHandler = new TaskHandler();
|
|
144
|
-
const modelHandler = new ModelHandler();
|
|
145
|
-
const structuredOutputHandler = new StructuredOutputlHandler();
|
|
146
|
-
const toolsHandler = new ToolsHandler();
|
|
147
|
-
messagesHandler.setNextHandler(taskHandler).setNextHandler(modelHandler).setNextHandler(structuredOutputHandler).setNextHandler(toolsHandler);
|
|
148
|
-
messagesHandler.handle(request, this.requestBuilder);
|
|
149
|
-
return this.requestBuilder.build();
|
|
150
|
-
}
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
// src/core/endpoint/request-builder.ts
|
|
154
|
-
var RequestBuilder = class {
|
|
155
|
-
initialize() {
|
|
156
|
-
this.request = {};
|
|
157
|
-
}
|
|
158
|
-
build() {
|
|
159
|
-
return this.request;
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
// src/providers/openai/mapper.ts
|
|
164
|
-
var OpenAIResponsesMapper = class {
|
|
165
|
-
/**
|
|
166
|
-
* Convert domain Messages to Responses API instructions format
|
|
167
|
-
*
|
|
168
|
-
* The Responses API uses 'instructions' (system prompt) rather than messages array.
|
|
169
|
-
* For multi-turn conversations, use conversation.id or previous_response_id parameters.
|
|
170
|
-
*/
|
|
171
|
-
toInstructions(messages) {
|
|
172
|
-
if (messages.length === 0) {
|
|
173
|
-
throw new Error("[ResponsesMapper] Cannot create instructions from empty messages");
|
|
174
|
-
}
|
|
175
|
-
const systemMessage = messages.find((m) => m.role === "system");
|
|
176
|
-
if (systemMessage) {
|
|
177
|
-
return typeof systemMessage.content === "string" ? systemMessage.content : this.extractTextFromContent(systemMessage.content);
|
|
178
|
-
}
|
|
179
|
-
return "You are a helpful assistant.";
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Extract the user's input from messages
|
|
183
|
-
* Returns the last user message content for use in prompt variables.
|
|
184
|
-
* In Responses API, the actual user query is typically passed via prompt variables
|
|
185
|
-
* or handled through conversation continuation.
|
|
186
|
-
*/
|
|
187
|
-
extractUserInput(messages) {
|
|
188
|
-
const userMessages = messages.filter((m) => m.role === "user");
|
|
189
|
-
if (userMessages.length === 0) {
|
|
190
|
-
return "";
|
|
191
|
-
}
|
|
192
|
-
const lastUserMessage = userMessages[userMessages.length - 1];
|
|
193
|
-
return typeof lastUserMessage.content === "string" ? lastUserMessage.content : this.extractTextFromContent(lastUserMessage.content);
|
|
194
|
-
}
|
|
195
|
-
extractTextFromContent(content) {
|
|
196
|
-
return content.filter((part) => part.type === "text").map((part) => part.text).join(" ");
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Map tools to Responses API format
|
|
200
|
-
*/
|
|
201
|
-
toTools(tools) {
|
|
202
|
-
return tools.map((t) => ({
|
|
203
|
-
type: "function",
|
|
204
|
-
name: t.name,
|
|
205
|
-
description: t.description,
|
|
206
|
-
parameters: t.schema,
|
|
207
|
-
strict: true
|
|
208
|
-
// Enable strict mode by default for better validation
|
|
209
|
-
}));
|
|
210
|
-
}
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
// src/providers/openai/builder.ts
|
|
214
|
-
var import_zod = require("openai/helpers/zod");
|
|
215
|
-
|
|
216
|
-
// src/types/request.ts
|
|
217
|
-
var ReasoningEffort = /* @__PURE__ */ ((ReasoningEffort2) => {
|
|
218
|
-
ReasoningEffort2["NONE"] = "none";
|
|
219
|
-
ReasoningEffort2["LOW"] = "low";
|
|
220
|
-
ReasoningEffort2["MEDIUM"] = "medium";
|
|
221
|
-
ReasoningEffort2["HIGH"] = "high";
|
|
222
|
-
ReasoningEffort2["MAX"] = "max";
|
|
223
|
-
return ReasoningEffort2;
|
|
224
|
-
})(ReasoningEffort || {});
|
|
225
|
-
|
|
226
|
-
// src/providers/openai/builder.ts
|
|
227
|
-
var OpenAIResponsesBuilder = class extends RequestBuilder {
|
|
228
|
-
constructor(mapper = new OpenAIResponsesMapper()) {
|
|
229
|
-
super();
|
|
230
|
-
this.mapper = mapper;
|
|
231
|
-
}
|
|
232
|
-
addModel(model) {
|
|
233
|
-
this.request.model = model;
|
|
42
|
+
addItem(item) {
|
|
43
|
+
this.items.push(item);
|
|
234
44
|
return this;
|
|
235
45
|
}
|
|
236
|
-
|
|
237
|
-
this.
|
|
46
|
+
addItems(items) {
|
|
47
|
+
this.items.push(...items);
|
|
238
48
|
return this;
|
|
239
49
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
if (instructions && instructions !== "You are a helpful assistant.") {
|
|
243
|
-
this.request.instructions = instructions;
|
|
244
|
-
}
|
|
245
|
-
return this;
|
|
50
|
+
getItems() {
|
|
51
|
+
return this.items;
|
|
246
52
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
};
|
|
251
|
-
return this;
|
|
53
|
+
static create(projectId) {
|
|
54
|
+
const id = crypto.randomUUID();
|
|
55
|
+
return new _Context(id, projectId, []);
|
|
252
56
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
type: "function",
|
|
256
|
-
name: tool.name,
|
|
257
|
-
description: tool.description,
|
|
258
|
-
parameters: tool.schema
|
|
259
|
-
}));
|
|
260
|
-
return this;
|
|
57
|
+
static rehydrate(data) {
|
|
58
|
+
return new _Context(data.id, data.projectId, data.items);
|
|
261
59
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
if (effort === "none" /* NONE */) {
|
|
265
|
-
reasoningEffort = "none";
|
|
266
|
-
} else if (effort === "low" /* LOW */) {
|
|
267
|
-
reasoningEffort = "low";
|
|
268
|
-
} else if (effort === "medium" /* MEDIUM */) {
|
|
269
|
-
reasoningEffort = "medium";
|
|
270
|
-
} else if (effort === "high" /* HIGH */) {
|
|
271
|
-
reasoningEffort = "high";
|
|
272
|
-
} else if (effort === "max" /* MAX */) {
|
|
273
|
-
reasoningEffort = "xhigh";
|
|
274
|
-
}
|
|
275
|
-
this.request.reasoning = {
|
|
276
|
-
effort: reasoningEffort
|
|
277
|
-
};
|
|
278
|
-
return this;
|
|
60
|
+
toJSON() {
|
|
61
|
+
return this.items.map((item) => item.toJSON());
|
|
279
62
|
}
|
|
280
63
|
};
|
|
281
64
|
|
|
282
|
-
// src/
|
|
283
|
-
var
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
this.client = client;
|
|
287
|
-
}
|
|
288
|
-
async send(request) {
|
|
289
|
-
return await this.client.responses.create(request);
|
|
65
|
+
// src/domain/context-runtime/context-item.ts
|
|
66
|
+
var ContextItem = class {
|
|
67
|
+
getType() {
|
|
68
|
+
return this.type;
|
|
290
69
|
}
|
|
291
70
|
};
|
|
292
71
|
|
|
293
|
-
// src/
|
|
294
|
-
var
|
|
295
|
-
var OpenAIParserClient = class {
|
|
296
|
-
constructor(client = new import_openai2.default()) {
|
|
297
|
-
this.client = client;
|
|
298
|
-
}
|
|
299
|
-
async send(request) {
|
|
300
|
-
return await this.client.responses.parse(request);
|
|
301
|
-
}
|
|
72
|
+
// src/domain/context-runtime/content.ts
|
|
73
|
+
var Content = class {
|
|
302
74
|
};
|
|
303
75
|
|
|
304
|
-
// src/
|
|
305
|
-
var
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
return new OpenAIDefaultClient();
|
|
311
|
-
}
|
|
76
|
+
// src/domain/context-runtime/content/input-text.ts
|
|
77
|
+
var InputText = class _InputText extends Content {
|
|
78
|
+
constructor(text) {
|
|
79
|
+
super();
|
|
80
|
+
this.text = text;
|
|
81
|
+
this.type = "input_text";
|
|
312
82
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
// src/core/endpoint/response-handler.ts
|
|
316
|
-
var ResponseHandler = class {
|
|
317
|
-
setNextHandler(responseHandler) {
|
|
318
|
-
this.nextHandler = responseHandler;
|
|
319
|
-
return this.nextHandler;
|
|
83
|
+
static create(text) {
|
|
84
|
+
return new _InputText(text);
|
|
320
85
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
// src/providers/openai/response-handler/output-parsed.ts
|
|
324
|
-
var OutputParsedHandler = class extends ResponseHandler {
|
|
325
|
-
async handle(mozaikResponse) {
|
|
326
|
-
const providerResponse = mozaikResponse.providerResponse;
|
|
327
|
-
if (providerResponse.output_parsed) {
|
|
328
|
-
mozaikResponse.setResponseData(providerResponse.output_parsed);
|
|
329
|
-
return mozaikResponse;
|
|
330
|
-
}
|
|
331
|
-
return await this.nextHandler.handle(mozaikResponse);
|
|
86
|
+
static rehydrate(data) {
|
|
87
|
+
return new _InputText(data.text);
|
|
332
88
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
var _a, _b;
|
|
339
|
-
const providerResponse = mozaikResponse.providerResponse;
|
|
340
|
-
const firstOutput = (_a = providerResponse.output) == null ? void 0 : _a[0];
|
|
341
|
-
if (firstOutput && "content" in firstOutput) {
|
|
342
|
-
const firstContent = (_b = firstOutput.content) == null ? void 0 : _b[0];
|
|
343
|
-
if (firstContent && "text" in firstContent) {
|
|
344
|
-
mozaikResponse.setResponseData(firstContent.text);
|
|
345
|
-
return mozaikResponse;
|
|
89
|
+
toJSON() {
|
|
90
|
+
return [
|
|
91
|
+
{
|
|
92
|
+
type: this.type,
|
|
93
|
+
text: this.text
|
|
346
94
|
}
|
|
347
|
-
|
|
348
|
-
return await this.nextHandler.handle(mozaikResponse);
|
|
95
|
+
];
|
|
349
96
|
}
|
|
350
97
|
};
|
|
351
98
|
|
|
352
|
-
// src/
|
|
353
|
-
var
|
|
354
|
-
|
|
355
|
-
const providerResponse = mozaikResponse.providerResponse;
|
|
356
|
-
if (providerResponse.output_text) {
|
|
357
|
-
mozaikResponse.setResponseData(providerResponse.output_text);
|
|
358
|
-
return mozaikResponse;
|
|
359
|
-
}
|
|
360
|
-
return await this.nextHandler.handle(mozaikResponse);
|
|
361
|
-
}
|
|
362
|
-
};
|
|
363
|
-
|
|
364
|
-
// src/core/usage-entry.ts
|
|
365
|
-
var UsageEntry = class {
|
|
366
|
-
constructor(priceInUsd, model) {
|
|
367
|
-
this.priceInUsd = priceInUsd;
|
|
368
|
-
this.model = model;
|
|
369
|
-
}
|
|
370
|
-
};
|
|
371
|
-
|
|
372
|
-
// src/providers/openai/model-pricing.ts
|
|
373
|
-
var OpenAIModelPricing = class {
|
|
374
|
-
calculateTotalCost(inputTokens, outputTokens, cachedInputTokens) {
|
|
375
|
-
const inputCost = (inputTokens - cachedInputTokens) * this.inputPricePer1MToken / 1e6;
|
|
376
|
-
const outputCost = outputTokens * this.outputPricePer1MToken / 1e6;
|
|
377
|
-
const cachedCost = cachedInputTokens * this.cachedPricePer1MToken / 1e6;
|
|
378
|
-
return inputCost + outputCost + cachedCost;
|
|
379
|
-
}
|
|
380
|
-
getPriceInUsd(modelName, inputTokens, outputTokens, cachedInputTokens) {
|
|
381
|
-
if (modelName.startsWith("gpt-5-mini")) {
|
|
382
|
-
this.inputPricePer1MToken = 0.25;
|
|
383
|
-
this.outputPricePer1MToken = 2;
|
|
384
|
-
this.cachedPricePer1MToken = 0.025;
|
|
385
|
-
return this.calculateTotalCost(inputTokens, outputTokens, cachedInputTokens);
|
|
386
|
-
} else if (modelName.startsWith("gpt-5-nano")) {
|
|
387
|
-
this.inputPricePer1MToken = 0.05;
|
|
388
|
-
this.outputPricePer1MToken = 0.4;
|
|
389
|
-
this.cachedPricePer1MToken = 5e-3;
|
|
390
|
-
return this.calculateTotalCost(inputTokens, outputTokens, cachedInputTokens);
|
|
391
|
-
} else if (modelName.startsWith("gpt-5.1")) {
|
|
392
|
-
this.inputPricePer1MToken = 1.25;
|
|
393
|
-
this.outputPricePer1MToken = 10;
|
|
394
|
-
this.cachedPricePer1MToken = 0.125;
|
|
395
|
-
return this.calculateTotalCost(inputTokens, outputTokens, cachedInputTokens);
|
|
396
|
-
} else if (modelName.startsWith("gpt-5")) {
|
|
397
|
-
this.inputPricePer1MToken = 1.25;
|
|
398
|
-
this.outputPricePer1MToken = 10;
|
|
399
|
-
this.cachedPricePer1MToken = 0.125;
|
|
400
|
-
return this.calculateTotalCost(inputTokens, outputTokens, cachedInputTokens);
|
|
401
|
-
}
|
|
402
|
-
throw new Error(`Model name ${modelName} is not supported for this pricing`);
|
|
403
|
-
}
|
|
404
|
-
};
|
|
405
|
-
|
|
406
|
-
// src/providers/openai/response-handler/function-calls.ts
|
|
407
|
-
var FunctionCallsHandler = class extends ResponseHandler {
|
|
408
|
-
constructor(request, tools) {
|
|
99
|
+
// src/domain/context-runtime/input/user-message.ts
|
|
100
|
+
var UserMessage = class _UserMessage extends ContextItem {
|
|
101
|
+
constructor(content) {
|
|
409
102
|
super();
|
|
410
|
-
this.
|
|
411
|
-
this.
|
|
412
|
-
this.
|
|
413
|
-
}
|
|
414
|
-
hasToolCalls(response) {
|
|
415
|
-
var _a;
|
|
416
|
-
return (_a = response.output) == null ? void 0 : _a.some((item) => item.type === "function_call");
|
|
417
|
-
}
|
|
418
|
-
extractToolCalls(response) {
|
|
419
|
-
var _a;
|
|
420
|
-
return ((_a = response.output) == null ? void 0 : _a.filter((item) => item.type === "function_call")) || [];
|
|
103
|
+
this.type = "message";
|
|
104
|
+
this.role = "user";
|
|
105
|
+
this.content = content;
|
|
421
106
|
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
return
|
|
107
|
+
static create(text) {
|
|
108
|
+
const content = InputText.create(text);
|
|
109
|
+
return new _UserMessage(content);
|
|
425
110
|
}
|
|
426
|
-
|
|
427
|
-
const
|
|
428
|
-
return
|
|
111
|
+
static rehydrate(data) {
|
|
112
|
+
const content = InputText.rehydrate(data);
|
|
113
|
+
return new _UserMessage(content);
|
|
429
114
|
}
|
|
430
|
-
|
|
115
|
+
toJSON() {
|
|
431
116
|
return {
|
|
432
|
-
type:
|
|
433
|
-
|
|
434
|
-
|
|
117
|
+
type: this.type,
|
|
118
|
+
role: this.role,
|
|
119
|
+
content: this.content.toJSON()
|
|
435
120
|
};
|
|
436
121
|
}
|
|
437
|
-
async executeToolCalls(toolCalls, tools) {
|
|
438
|
-
var _a;
|
|
439
|
-
const results = [];
|
|
440
|
-
for (const call of toolCalls) {
|
|
441
|
-
const tool = this.resolveTool(call, tools);
|
|
442
|
-
if (!tool) {
|
|
443
|
-
results.push(
|
|
444
|
-
this.formatToolResult(call.call_id, {
|
|
445
|
-
error: `Unknown tool: ${call.name}`
|
|
446
|
-
})
|
|
447
|
-
);
|
|
448
|
-
continue;
|
|
449
|
-
}
|
|
450
|
-
try {
|
|
451
|
-
const result = await this.executeTool(tool, call.arguments);
|
|
452
|
-
results.push(this.formatToolResult(call.call_id, result));
|
|
453
|
-
} catch (err) {
|
|
454
|
-
results.push(
|
|
455
|
-
this.formatToolResult(call.call_id, {
|
|
456
|
-
error: (_a = err.message) != null ? _a : "Tool execution failed"
|
|
457
|
-
})
|
|
458
|
-
);
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
return results;
|
|
462
|
-
}
|
|
463
|
-
async handle(mozaikResponse) {
|
|
464
|
-
var _a, _b;
|
|
465
|
-
let providerResponse = mozaikResponse.providerResponse;
|
|
466
|
-
let toolCallingResponse;
|
|
467
|
-
while (this.hasToolCalls(providerResponse)) {
|
|
468
|
-
const toolCalls = this.extractToolCalls(providerResponse);
|
|
469
|
-
const toolResults = await this.executeToolCalls(toolCalls, this.tools);
|
|
470
|
-
this.request.input = toolResults;
|
|
471
|
-
this.request.previous_response_id = providerResponse.id;
|
|
472
|
-
toolCallingResponse = await this.client.send(this.request);
|
|
473
|
-
const openAIModelPricing = new OpenAIModelPricing();
|
|
474
|
-
const usage = toolCallingResponse.usage;
|
|
475
|
-
const totalCost = openAIModelPricing.getPriceInUsd(
|
|
476
|
-
providerResponse.model,
|
|
477
|
-
usage.input_tokens,
|
|
478
|
-
usage.output_tokens,
|
|
479
|
-
(_b = (_a = usage.input_token_details) == null ? void 0 : _a.cached_tokens) != null ? _b : 0
|
|
480
|
-
);
|
|
481
|
-
mozaikResponse.addUsageEntry(new UsageEntry(totalCost, providerResponse.model));
|
|
482
|
-
mozaikResponse.setProviderResponse(toolCallingResponse);
|
|
483
|
-
mozaikResponse.setResponseData(toolCallingResponse);
|
|
484
|
-
providerResponse = toolCallingResponse;
|
|
485
|
-
}
|
|
486
|
-
return await this.nextHandler.handle(mozaikResponse);
|
|
487
|
-
}
|
|
488
122
|
};
|
|
489
123
|
|
|
490
|
-
// src/
|
|
491
|
-
var
|
|
492
|
-
constructor() {
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
this.
|
|
497
|
-
return this;
|
|
498
|
-
}
|
|
499
|
-
addUsageEntry(usageEntry) {
|
|
500
|
-
this.usageEntries.push(usageEntry);
|
|
501
|
-
return this;
|
|
502
|
-
}
|
|
503
|
-
setResponseData(response) {
|
|
504
|
-
this.responseData = response;
|
|
505
|
-
return this;
|
|
124
|
+
// src/domain/context-runtime/input/developer-message.ts
|
|
125
|
+
var DeveloperMessage = class _DeveloperMessage extends ContextItem {
|
|
126
|
+
constructor(content) {
|
|
127
|
+
super();
|
|
128
|
+
this.type = "message";
|
|
129
|
+
this.role = "developer";
|
|
130
|
+
this.content = content;
|
|
506
131
|
}
|
|
507
|
-
|
|
132
|
+
toJSON() {
|
|
508
133
|
return {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
},
|
|
513
|
-
totalCost: this.usageEntries.reduce((acc, entry) => acc + entry.priceInUsd, 0)
|
|
134
|
+
type: this.type,
|
|
135
|
+
role: this.role,
|
|
136
|
+
content: this.content.toJSON()
|
|
514
137
|
};
|
|
515
138
|
}
|
|
516
|
-
|
|
517
|
-
|
|
139
|
+
static create(text) {
|
|
140
|
+
const content = InputText.create(text);
|
|
141
|
+
return new _DeveloperMessage(content);
|
|
518
142
|
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
var UsageHandler = class extends ResponseHandler {
|
|
523
|
-
async handle(mozaikResponse) {
|
|
524
|
-
var _a, _b;
|
|
525
|
-
const providerResponse = mozaikResponse.providerResponse;
|
|
526
|
-
const usage = providerResponse.usage;
|
|
527
|
-
const openAIModelPricing = new OpenAIModelPricing();
|
|
528
|
-
const totalCost = openAIModelPricing.getPriceInUsd(
|
|
529
|
-
providerResponse.model,
|
|
530
|
-
usage.input_tokens,
|
|
531
|
-
usage.output_tokens,
|
|
532
|
-
(_b = (_a = usage.input_token_details) == null ? void 0 : _a.cached_tokens) != null ? _b : 0
|
|
533
|
-
);
|
|
534
|
-
mozaikResponse.addUsageEntry(new UsageEntry(totalCost, providerResponse.model));
|
|
535
|
-
return await this.nextHandler.handle(mozaikResponse);
|
|
143
|
+
static rehydrate(data) {
|
|
144
|
+
const content = InputText.rehydrate(data);
|
|
145
|
+
return new _DeveloperMessage(content);
|
|
536
146
|
}
|
|
537
147
|
};
|
|
538
148
|
|
|
539
|
-
// src/
|
|
540
|
-
var
|
|
541
|
-
constructor() {
|
|
149
|
+
// src/domain/context-runtime/content/output-text.ts
|
|
150
|
+
var OutputText = class _OutputText extends Content {
|
|
151
|
+
constructor(text) {
|
|
542
152
|
super();
|
|
543
|
-
this.
|
|
153
|
+
this.text = text;
|
|
154
|
+
this.type = "output_text";
|
|
544
155
|
}
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
const request = this.buildRequest(mozaikRequest);
|
|
548
|
-
const client = OpenAIClientResolver.resolve(request);
|
|
549
|
-
const response = await client.send(request);
|
|
550
|
-
const mozaikResponse = new MozaikResponse();
|
|
551
|
-
mozaikResponse.setProviderResponse(response);
|
|
552
|
-
const usageHandler = new UsageHandler();
|
|
553
|
-
const functionCallsHandler = new FunctionCallsHandler(
|
|
554
|
-
request,
|
|
555
|
-
mozaikRequest.tools ? mozaikRequest.tools : []
|
|
556
|
-
);
|
|
557
|
-
const outputParsedHandler = new OutputParsedHandler();
|
|
558
|
-
const outputTextHandler = new OutputTextHandler();
|
|
559
|
-
const contentHandler = new ContentHandler();
|
|
560
|
-
usageHandler.setNextHandler(functionCallsHandler).setNextHandler(outputParsedHandler).setNextHandler(outputTextHandler).setNextHandler(contentHandler);
|
|
561
|
-
const responseHandler = usageHandler;
|
|
562
|
-
const result = await responseHandler.handle(mozaikResponse);
|
|
563
|
-
return result.getResponse();
|
|
564
|
-
} catch (error) {
|
|
565
|
-
console.warn("[OpenAIProvider] Responses API request failed:", error);
|
|
566
|
-
throw error;
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
};
|
|
570
|
-
|
|
571
|
-
// src/providers/anthropic/mapper.ts
|
|
572
|
-
var AnthropicMapper = class {
|
|
573
|
-
/**
|
|
574
|
-
* Transforms domain messages to Anthropic API format.
|
|
575
|
-
* Separates system messages from conversation messages.
|
|
576
|
-
*/
|
|
577
|
-
toMessages(messages) {
|
|
578
|
-
const anthropicMessages = [];
|
|
579
|
-
let systemPrompt;
|
|
580
|
-
for (const msg of messages) {
|
|
581
|
-
if (msg.role === "system") {
|
|
582
|
-
const content = typeof msg.content === "string" ? msg.content : msg.content.map((p) => p.text).join("\n");
|
|
583
|
-
systemPrompt = systemPrompt ? `${systemPrompt}
|
|
584
|
-
|
|
585
|
-
${content}` : content;
|
|
586
|
-
continue;
|
|
587
|
-
}
|
|
588
|
-
if (msg.role === "tool") {
|
|
589
|
-
continue;
|
|
590
|
-
}
|
|
591
|
-
if (msg.role === "user" || msg.role === "assistant") {
|
|
592
|
-
if (typeof msg.content === "string") {
|
|
593
|
-
anthropicMessages.push({
|
|
594
|
-
role: msg.role,
|
|
595
|
-
content: msg.content
|
|
596
|
-
});
|
|
597
|
-
} else {
|
|
598
|
-
const contentBlocks = msg.content.map((part) => {
|
|
599
|
-
if (part.type === "text") {
|
|
600
|
-
return {
|
|
601
|
-
type: "text",
|
|
602
|
-
text: part.text
|
|
603
|
-
};
|
|
604
|
-
} else if (part.type === "image_url") {
|
|
605
|
-
const imageUrl = part.url;
|
|
606
|
-
if (imageUrl.startsWith("data:image")) {
|
|
607
|
-
const matches = imageUrl.match(/data:image\/(\w+);base64,(.+)/);
|
|
608
|
-
if (matches) {
|
|
609
|
-
const [, mediaType, data] = matches;
|
|
610
|
-
return {
|
|
611
|
-
type: "image",
|
|
612
|
-
source: {
|
|
613
|
-
type: "base64",
|
|
614
|
-
media_type: `image/${mediaType}`,
|
|
615
|
-
data
|
|
616
|
-
}
|
|
617
|
-
};
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
throw new Error(
|
|
621
|
-
"[AnthropicMapper] Image URLs must be base64-encoded. Convert to data:image/[type];base64,[data] format."
|
|
622
|
-
);
|
|
623
|
-
}
|
|
624
|
-
return { type: "text", text: "" };
|
|
625
|
-
});
|
|
626
|
-
anthropicMessages.push({
|
|
627
|
-
role: msg.role,
|
|
628
|
-
content: contentBlocks
|
|
629
|
-
});
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
const validated = this.ensureAlternatingRoles(anthropicMessages);
|
|
634
|
-
return {
|
|
635
|
-
messages: validated,
|
|
636
|
-
system: systemPrompt
|
|
637
|
-
};
|
|
156
|
+
static rehydrate(data) {
|
|
157
|
+
return new _OutputText(data.text);
|
|
638
158
|
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
if (messages.length === 0) return messages;
|
|
645
|
-
const result = [];
|
|
646
|
-
let lastRole;
|
|
647
|
-
for (const msg of messages) {
|
|
648
|
-
if (lastRole === msg.role && result.length > 0) {
|
|
649
|
-
const lastMsg = result[result.length - 1];
|
|
650
|
-
if (typeof lastMsg.content === "string" && typeof msg.content === "string") {
|
|
651
|
-
lastMsg.content = `${lastMsg.content}
|
|
652
|
-
${msg.content}`;
|
|
653
|
-
} else {
|
|
654
|
-
const lastContent = Array.isArray(lastMsg.content) ? lastMsg.content : [{ type: "text", text: lastMsg.content }];
|
|
655
|
-
const newContent = Array.isArray(msg.content) ? msg.content : [{ type: "text", text: msg.content }];
|
|
656
|
-
lastMsg.content = [...lastContent, ...newContent];
|
|
657
|
-
}
|
|
658
|
-
} else {
|
|
659
|
-
result.push(msg);
|
|
660
|
-
lastRole = msg.role;
|
|
159
|
+
toJSON() {
|
|
160
|
+
return [
|
|
161
|
+
{
|
|
162
|
+
type: this.type,
|
|
163
|
+
text: this.text
|
|
661
164
|
}
|
|
662
|
-
|
|
663
|
-
if (result.length > 0 && result[0].role !== "user") {
|
|
664
|
-
throw new Error(
|
|
665
|
-
"[AnthropicMapper] First message must be from user. Anthropic API requires conversations to start with a user message."
|
|
666
|
-
);
|
|
667
|
-
}
|
|
668
|
-
return result;
|
|
165
|
+
];
|
|
669
166
|
}
|
|
670
167
|
};
|
|
671
168
|
|
|
672
|
-
// src/
|
|
673
|
-
var
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
this.
|
|
678
|
-
|
|
679
|
-
addModel(model) {
|
|
680
|
-
this.request.model = ANTHROPIC_MODEL_MAP[model];
|
|
681
|
-
return this;
|
|
682
|
-
}
|
|
683
|
-
addTask(task) {
|
|
684
|
-
const message = {
|
|
685
|
-
role: "user",
|
|
686
|
-
content: task
|
|
687
|
-
};
|
|
688
|
-
if (!this.request.messages) {
|
|
689
|
-
this.request.messages = [];
|
|
690
|
-
}
|
|
691
|
-
this.request.messages.push(message);
|
|
692
|
-
return this;
|
|
693
|
-
}
|
|
694
|
-
addMessages(messages) {
|
|
695
|
-
const { messages: anthropicMessages, system } = this.mapper.toMessages(messages);
|
|
696
|
-
this.request.messages = anthropicMessages;
|
|
697
|
-
if (system) {
|
|
698
|
-
this.request.system = system;
|
|
699
|
-
}
|
|
700
|
-
return this;
|
|
701
|
-
}
|
|
702
|
-
addStructuredOutput(schema) {
|
|
703
|
-
this.request.betas = ["structured-outputs-2025-11-13"];
|
|
704
|
-
this.request.output_format = (0, import_zod2.betaZodOutputFormat)(schema);
|
|
705
|
-
return this;
|
|
169
|
+
// src/domain/context-runtime/output/model-message.ts
|
|
170
|
+
var ModelMessage = class _ModelMessage extends ContextItem {
|
|
171
|
+
constructor(content) {
|
|
172
|
+
super();
|
|
173
|
+
this.type = "message";
|
|
174
|
+
this.role = "assistant";
|
|
175
|
+
this.content = content;
|
|
706
176
|
}
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
description: tool.description,
|
|
711
|
-
input_schema: tool.schema
|
|
712
|
-
}));
|
|
713
|
-
return this;
|
|
177
|
+
static rehydrate(data) {
|
|
178
|
+
const content = OutputText.rehydrate(data);
|
|
179
|
+
return new _ModelMessage(content);
|
|
714
180
|
}
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
reasoningEffort = "low";
|
|
721
|
-
} else if (effort === "medium" /* MEDIUM */) {
|
|
722
|
-
reasoningEffort = "medium";
|
|
723
|
-
} else if (effort === "high" /* HIGH */) {
|
|
724
|
-
reasoningEffort = "high";
|
|
725
|
-
} else if (effort === "max" /* MAX */) {
|
|
726
|
-
reasoningEffort = "max";
|
|
727
|
-
}
|
|
728
|
-
this.request.output_config = {
|
|
729
|
-
effort: reasoningEffort
|
|
181
|
+
toJSON() {
|
|
182
|
+
return {
|
|
183
|
+
type: this.type,
|
|
184
|
+
role: this.role,
|
|
185
|
+
content: this.content.toJSON()
|
|
730
186
|
};
|
|
731
|
-
return this;
|
|
732
|
-
}
|
|
733
|
-
build() {
|
|
734
|
-
if (!this.request.max_tokens) {
|
|
735
|
-
this.request.max_tokens = 1024;
|
|
736
|
-
}
|
|
737
|
-
return this.request;
|
|
738
|
-
}
|
|
739
|
-
};
|
|
740
|
-
|
|
741
|
-
// src/providers/anthropic/client/default.ts
|
|
742
|
-
var import_sdk = __toESM(require("@anthropic-ai/sdk"));
|
|
743
|
-
var AnthropicDefaultClient = class {
|
|
744
|
-
constructor(client = new import_sdk.default()) {
|
|
745
|
-
this.client = client;
|
|
746
|
-
}
|
|
747
|
-
async send(request) {
|
|
748
|
-
return await this.client.messages.create(request);
|
|
749
|
-
}
|
|
750
|
-
};
|
|
751
|
-
|
|
752
|
-
// src/providers/anthropic/client/parser.ts
|
|
753
|
-
var import_sdk2 = __toESM(require("@anthropic-ai/sdk"));
|
|
754
|
-
var AnthropicParserClient = class {
|
|
755
|
-
constructor(client = new import_sdk2.default()) {
|
|
756
|
-
this.client = client;
|
|
757
|
-
}
|
|
758
|
-
async send(request) {
|
|
759
|
-
return await this.client.beta.messages.parse(request);
|
|
760
|
-
}
|
|
761
|
-
};
|
|
762
|
-
|
|
763
|
-
// src/providers/anthropic/client/resolver.ts
|
|
764
|
-
var AnthropicClientResolver = class {
|
|
765
|
-
static resolve(request) {
|
|
766
|
-
return request.output_format ? new AnthropicParserClient() : new AnthropicDefaultClient();
|
|
767
187
|
}
|
|
768
188
|
};
|
|
769
189
|
|
|
770
|
-
// src/
|
|
771
|
-
var
|
|
772
|
-
|
|
773
|
-
const providerResponse = mozaikResponse.providerResponse;
|
|
774
|
-
if (providerResponse.parsed_output) {
|
|
775
|
-
mozaikResponse.setResponseData(providerResponse.parsed_output);
|
|
776
|
-
return mozaikResponse;
|
|
777
|
-
}
|
|
778
|
-
return await this.nextHandler.handle(mozaikResponse);
|
|
779
|
-
}
|
|
780
|
-
};
|
|
781
|
-
|
|
782
|
-
// src/providers/anthropic/response-handler/content.ts
|
|
783
|
-
var ContentHandler2 = class extends ResponseHandler {
|
|
784
|
-
async handle(mozaikResponse) {
|
|
785
|
-
const providerResponse = mozaikResponse.providerResponse;
|
|
786
|
-
const content = providerResponse.content.filter((block) => block.type === "text").map((block) => block.type === "text" ? block.text : "").join("");
|
|
787
|
-
if (content) {
|
|
788
|
-
mozaikResponse.setResponseData(content);
|
|
789
|
-
return mozaikResponse;
|
|
790
|
-
}
|
|
791
|
-
return await this.nextHandler.handle(mozaikResponse);
|
|
792
|
-
}
|
|
793
|
-
};
|
|
794
|
-
|
|
795
|
-
// src/providers/anthropic/model-pricing.ts
|
|
796
|
-
var AnthropicModelPricing = class {
|
|
797
|
-
calculateTotalCost(inputTokens, outputTokens) {
|
|
798
|
-
const inputCost = inputTokens * this.inputPricePer1MToken / 1e6;
|
|
799
|
-
const outputCost = outputTokens * this.outputPricePer1MToken / 1e6;
|
|
800
|
-
return inputCost + outputCost;
|
|
801
|
-
}
|
|
802
|
-
getPriceInUsd(modelName, inputTokens, outputTokens) {
|
|
803
|
-
if (modelName.startsWith("claude-sonnet-4-5")) {
|
|
804
|
-
this.inputPricePer1MToken = 3;
|
|
805
|
-
this.outputPricePer1MToken = 15;
|
|
806
|
-
return this.calculateTotalCost(inputTokens, outputTokens);
|
|
807
|
-
} else if (modelName.startsWith("claude-haiku-4-5")) {
|
|
808
|
-
this.inputPricePer1MToken = 1;
|
|
809
|
-
this.outputPricePer1MToken = 5;
|
|
810
|
-
return this.calculateTotalCost(inputTokens, outputTokens);
|
|
811
|
-
} else if (modelName.startsWith("claude-opus-4-5")) {
|
|
812
|
-
this.inputPricePer1MToken = 5;
|
|
813
|
-
this.outputPricePer1MToken = 25;
|
|
814
|
-
return this.calculateTotalCost(inputTokens, outputTokens);
|
|
815
|
-
}
|
|
816
|
-
throw new Error(`Model name ${modelName} is not supported for this pricing`);
|
|
817
|
-
}
|
|
818
|
-
};
|
|
819
|
-
|
|
820
|
-
// src/providers/anthropic/response-handler/tool-use.ts
|
|
821
|
-
var ToolUseHandler = class extends ResponseHandler {
|
|
822
|
-
constructor(request, tools) {
|
|
190
|
+
// src/domain/context-runtime/output/function-call.ts
|
|
191
|
+
var FunctionCall = class _FunctionCall extends ContextItem {
|
|
192
|
+
constructor(callId, name, args) {
|
|
823
193
|
super();
|
|
824
|
-
this.
|
|
825
|
-
this.
|
|
826
|
-
this.
|
|
827
|
-
|
|
828
|
-
async executeToolCalls(tools, toolUseBlocks) {
|
|
829
|
-
const results = [];
|
|
830
|
-
for (const toolUse of toolUseBlocks) {
|
|
831
|
-
const tool = tools == null ? void 0 : tools.find((t) => t.name === toolUse.name);
|
|
832
|
-
if (!tool) {
|
|
833
|
-
results.push({
|
|
834
|
-
type: "tool_result",
|
|
835
|
-
tool_use_id: toolUse.id,
|
|
836
|
-
content: JSON.stringify({ error: `Unknown tool: ${toolUse.name}` })
|
|
837
|
-
});
|
|
838
|
-
continue;
|
|
839
|
-
}
|
|
840
|
-
try {
|
|
841
|
-
const result = await tool.invoke(toolUse.input);
|
|
842
|
-
results.push({
|
|
843
|
-
type: "tool_result",
|
|
844
|
-
tool_use_id: toolUse.id,
|
|
845
|
-
content: JSON.stringify(result)
|
|
846
|
-
});
|
|
847
|
-
} catch (error) {
|
|
848
|
-
results.push({
|
|
849
|
-
type: "tool_result",
|
|
850
|
-
tool_use_id: toolUse.id,
|
|
851
|
-
content: JSON.stringify({ error: error.message })
|
|
852
|
-
});
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
return results;
|
|
856
|
-
}
|
|
857
|
-
async handle(mozaikResponse) {
|
|
858
|
-
let providerResponse = mozaikResponse.providerResponse;
|
|
859
|
-
while (providerResponse.stop_reason === "tool_use") {
|
|
860
|
-
const toolUseBlocks = providerResponse.content.filter(
|
|
861
|
-
(block) => block.type === "tool_use"
|
|
862
|
-
);
|
|
863
|
-
this.request.messages.push({
|
|
864
|
-
role: "assistant",
|
|
865
|
-
content: providerResponse.content
|
|
866
|
-
});
|
|
867
|
-
const toolResults = await this.executeToolCalls(this.tools, toolUseBlocks);
|
|
868
|
-
this.request.messages.push({
|
|
869
|
-
role: "user",
|
|
870
|
-
content: toolResults
|
|
871
|
-
});
|
|
872
|
-
const toolCallingResponse = await this.client.send(this.request);
|
|
873
|
-
const usage = toolCallingResponse.usage;
|
|
874
|
-
const anthropicModelPricing = new AnthropicModelPricing();
|
|
875
|
-
const totalCost = anthropicModelPricing.getPriceInUsd(
|
|
876
|
-
providerResponse.model,
|
|
877
|
-
usage.input_tokens,
|
|
878
|
-
usage.output_tokens
|
|
879
|
-
);
|
|
880
|
-
mozaikResponse.addUsageEntry(new UsageEntry(totalCost, toolCallingResponse.model.name));
|
|
881
|
-
mozaikResponse.setProviderResponse(toolCallingResponse);
|
|
882
|
-
providerResponse = toolCallingResponse;
|
|
883
|
-
}
|
|
884
|
-
return await this.nextHandler.handle(mozaikResponse);
|
|
885
|
-
}
|
|
886
|
-
};
|
|
887
|
-
|
|
888
|
-
// src/providers/anthropic/response-handler/usage.ts
|
|
889
|
-
var UsageHandler2 = class extends ResponseHandler {
|
|
890
|
-
async handle(mozaikResponse) {
|
|
891
|
-
const providerResponse = mozaikResponse.providerResponse;
|
|
892
|
-
const usage = providerResponse.usage;
|
|
893
|
-
const anthropicModelPricing = new AnthropicModelPricing();
|
|
894
|
-
const totalCost = anthropicModelPricing.getPriceInUsd(
|
|
895
|
-
providerResponse.model,
|
|
896
|
-
usage.input_tokens,
|
|
897
|
-
usage.output_tokens
|
|
898
|
-
);
|
|
899
|
-
if (usage) {
|
|
900
|
-
mozaikResponse.addUsageEntry(new UsageEntry(totalCost, providerResponse.model));
|
|
901
|
-
}
|
|
902
|
-
return await this.nextHandler.handle(mozaikResponse);
|
|
903
|
-
}
|
|
904
|
-
};
|
|
905
|
-
|
|
906
|
-
// src/providers/anthropic/response-handler/undhandled.ts
|
|
907
|
-
var UnhandledResponseHandler = class extends ResponseHandler {
|
|
908
|
-
async handle(mozaikResponse) {
|
|
909
|
-
var _a, _b;
|
|
910
|
-
const providerResponse = mozaikResponse.providerResponse;
|
|
911
|
-
const id = (_a = providerResponse == null ? void 0 : providerResponse.id) != null ? _a : "unknown";
|
|
912
|
-
const model = (_b = providerResponse == null ? void 0 : providerResponse.model) != null ? _b : "unknown";
|
|
913
|
-
throw new Error(`No response handler matched. response_id=${id} model=${model}`);
|
|
914
|
-
}
|
|
915
|
-
};
|
|
916
|
-
|
|
917
|
-
// src/providers/anthropic/endpoint.ts
|
|
918
|
-
var AnthropicEndpoint = class extends Endpoint {
|
|
919
|
-
constructor() {
|
|
920
|
-
super(...arguments);
|
|
921
|
-
this.requestBuilder = new AnthropicRequestBuilder();
|
|
922
|
-
}
|
|
923
|
-
async sendRequest(mozaikRequest) {
|
|
924
|
-
const providerRequest = this.buildRequest(mozaikRequest);
|
|
925
|
-
const client = AnthropicClientResolver.resolve(providerRequest);
|
|
926
|
-
const response = await client.send(providerRequest);
|
|
927
|
-
const mozaikResponse = new MozaikResponse();
|
|
928
|
-
mozaikResponse.setProviderResponse(response);
|
|
929
|
-
const usageHandler = new UsageHandler2();
|
|
930
|
-
const toolUseHandler = new ToolUseHandler(
|
|
931
|
-
providerRequest,
|
|
932
|
-
mozaikRequest.tools ? mozaikRequest.tools : []
|
|
933
|
-
);
|
|
934
|
-
const parsedOutputHandler = new ParsedOutputHandler();
|
|
935
|
-
const contentHandler = new ContentHandler2();
|
|
936
|
-
const unhandledResponseHandler = new UnhandledResponseHandler();
|
|
937
|
-
usageHandler.setNextHandler(toolUseHandler).setNextHandler(parsedOutputHandler).setNextHandler(contentHandler).setNextHandler(unhandledResponseHandler);
|
|
938
|
-
const responseHandler = usageHandler;
|
|
939
|
-
const result = await responseHandler.handle(mozaikResponse);
|
|
940
|
-
return result.getResponse();
|
|
941
|
-
}
|
|
942
|
-
};
|
|
943
|
-
|
|
944
|
-
// src/providers/endpoint-resolver.ts
|
|
945
|
-
var DefaultEndpointResolver = class extends EndpointResolver {
|
|
946
|
-
isOpenAIModel(value) {
|
|
947
|
-
return OPENAI_MODELS.includes(value);
|
|
948
|
-
}
|
|
949
|
-
isAnthropicModel(value) {
|
|
950
|
-
return ANTHROPIC_MODELS.includes(value);
|
|
951
|
-
}
|
|
952
|
-
resolve(model) {
|
|
953
|
-
if (this.isOpenAIModel(model)) {
|
|
954
|
-
return new OpenAIResponses();
|
|
955
|
-
} else if (this.isAnthropicModel(model)) {
|
|
956
|
-
return new AnthropicEndpoint();
|
|
957
|
-
}
|
|
958
|
-
throw new Error("Provider not found");
|
|
959
|
-
}
|
|
960
|
-
};
|
|
961
|
-
|
|
962
|
-
// src/core/agents/agent.ts
|
|
963
|
-
var MozaikAgent = class {
|
|
964
|
-
constructor(request) {
|
|
965
|
-
this.gateway = new RequestGateway(new DefaultEndpointResolver());
|
|
966
|
-
this.request = request;
|
|
967
|
-
}
|
|
968
|
-
setModel(model) {
|
|
969
|
-
this.request.model = model;
|
|
970
|
-
}
|
|
971
|
-
setMessages(messages) {
|
|
972
|
-
this.request.messages = messages;
|
|
973
|
-
}
|
|
974
|
-
setTask(task) {
|
|
975
|
-
this.request.task = task;
|
|
976
|
-
}
|
|
977
|
-
setStructuredOutput(schema) {
|
|
978
|
-
this.request.structuredOutput = schema;
|
|
979
|
-
}
|
|
980
|
-
async act(task) {
|
|
981
|
-
if (task) {
|
|
982
|
-
this.request.task = task;
|
|
983
|
-
}
|
|
984
|
-
return await this.gateway.invoke(this.request);
|
|
985
|
-
}
|
|
986
|
-
};
|
|
987
|
-
|
|
988
|
-
// src/core/workflow/schema/plan.ts
|
|
989
|
-
var import_zod3 = __toESM(require("zod"));
|
|
990
|
-
var ModelSchema = import_zod3.default.enum([...OPENAI_MODELS, ...ANTHROPIC_MODELS]);
|
|
991
|
-
var TaskPlanNodeSchema = import_zod3.default.object({
|
|
992
|
-
kind: import_zod3.default.literal("task"),
|
|
993
|
-
task: import_zod3.default.string(),
|
|
994
|
-
model: ModelSchema
|
|
995
|
-
});
|
|
996
|
-
var WorkflowPlanNodeSchema = import_zod3.default.lazy(
|
|
997
|
-
() => import_zod3.default.object({
|
|
998
|
-
kind: import_zod3.default.literal("workflow"),
|
|
999
|
-
mode: import_zod3.default.enum(["sequential", "parallel"]),
|
|
1000
|
-
units: import_zod3.default.array(PlanNodeSchema)
|
|
1001
|
-
})
|
|
1002
|
-
);
|
|
1003
|
-
var PlanNodeSchema = TaskPlanNodeSchema.or(WorkflowPlanNodeSchema);
|
|
1004
|
-
var PlanSchema = import_zod3.default.object({
|
|
1005
|
-
root: PlanNodeSchema
|
|
1006
|
-
});
|
|
1007
|
-
|
|
1008
|
-
// src/core/workflow/execution/parallel.ts
|
|
1009
|
-
var ParallelExecution = class {
|
|
1010
|
-
async execute(workflow, hook) {
|
|
1011
|
-
const promises = [];
|
|
1012
|
-
for (const u of workflow.units) {
|
|
1013
|
-
promises.push(u.execute(hook));
|
|
1014
|
-
}
|
|
1015
|
-
const results = await Promise.all(promises);
|
|
1016
|
-
return results;
|
|
1017
|
-
}
|
|
1018
|
-
};
|
|
1019
|
-
|
|
1020
|
-
// src/core/workflow/execution/sequential.ts
|
|
1021
|
-
var SequentalExecution = class {
|
|
1022
|
-
async execute(workflow, hook) {
|
|
1023
|
-
const results = [];
|
|
1024
|
-
for (const u of workflow.units) {
|
|
1025
|
-
results.push(await u.execute(hook));
|
|
1026
|
-
}
|
|
1027
|
-
return results;
|
|
1028
|
-
}
|
|
1029
|
-
};
|
|
1030
|
-
|
|
1031
|
-
// src/core/workflow/execution/strategy-factory.ts
|
|
1032
|
-
var ExecutionStrategyFactory = class {
|
|
1033
|
-
static create(mode) {
|
|
1034
|
-
let strategy;
|
|
1035
|
-
if (mode == "parallel") {
|
|
1036
|
-
strategy = new ParallelExecution();
|
|
1037
|
-
} else {
|
|
1038
|
-
strategy = new SequentalExecution();
|
|
1039
|
-
}
|
|
1040
|
-
return strategy;
|
|
1041
|
-
}
|
|
1042
|
-
};
|
|
1043
|
-
|
|
1044
|
-
// src/core/workflow/hooks/cluster.ts
|
|
1045
|
-
var ClusterHook = class {
|
|
1046
|
-
constructor(hooks) {
|
|
1047
|
-
this.hooks = hooks;
|
|
1048
|
-
}
|
|
1049
|
-
beforeTask(task) {
|
|
1050
|
-
this.hooks.forEach((h) => h.beforeTask(task));
|
|
1051
|
-
}
|
|
1052
|
-
afterTask(task, result) {
|
|
1053
|
-
this.hooks.forEach((h) => h.afterTask(task, result));
|
|
194
|
+
this.type = "function_call";
|
|
195
|
+
this.callId = callId;
|
|
196
|
+
this.name = name;
|
|
197
|
+
this.args = args;
|
|
1054
198
|
}
|
|
1055
|
-
|
|
1056
|
-
|
|
199
|
+
static rehydrate(data) {
|
|
200
|
+
return new _FunctionCall(data.callId, data.name, data.args);
|
|
1057
201
|
}
|
|
1058
|
-
|
|
1059
|
-
|
|
202
|
+
toJSON() {
|
|
203
|
+
return {
|
|
204
|
+
type: this.type,
|
|
205
|
+
callId: this.callId,
|
|
206
|
+
name: this.name,
|
|
207
|
+
arguments: this.args
|
|
208
|
+
};
|
|
1060
209
|
}
|
|
1061
210
|
};
|
|
1062
211
|
|
|
1063
|
-
// src/
|
|
1064
|
-
var
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
212
|
+
// src/domain/context-runtime/output/reasoning.ts
|
|
213
|
+
var Reasoning = class _Reasoning extends ContextItem {
|
|
214
|
+
constructor(content, encryptedContent, summary = []) {
|
|
215
|
+
super();
|
|
216
|
+
this.type = "reasoning";
|
|
217
|
+
this.content = content;
|
|
218
|
+
this.encryptedContent = encryptedContent;
|
|
219
|
+
this.summary = summary;
|
|
1070
220
|
}
|
|
1071
|
-
|
|
1072
|
-
|
|
221
|
+
static rehydrate(data) {
|
|
222
|
+
return new _Reasoning(data.content, data.encryptedContent, data.summary);
|
|
1073
223
|
}
|
|
1074
|
-
|
|
1075
|
-
|
|
224
|
+
toJSON() {
|
|
225
|
+
var _a;
|
|
226
|
+
return {
|
|
227
|
+
type: this.type,
|
|
228
|
+
content: (_a = this.content) == null ? void 0 : _a.toJSON(),
|
|
229
|
+
encryptedContent: this.encryptedContent,
|
|
230
|
+
summary: this.summary.map((s) => s.toJSON())
|
|
231
|
+
};
|
|
1076
232
|
}
|
|
1077
233
|
};
|
|
1078
234
|
|
|
1079
|
-
// src/
|
|
1080
|
-
var
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
// src/core/workflow/workflow.ts
|
|
1086
|
-
var Workflow = class extends WorkUnit {
|
|
1087
|
-
constructor(mode, units) {
|
|
1088
|
-
super();
|
|
1089
|
-
this.mode = mode;
|
|
1090
|
-
this.units = units;
|
|
1091
|
-
}
|
|
1092
|
-
async execute(hook = DEFAULT_CLUSTER_HOOK) {
|
|
1093
|
-
hook.beforeWorkflow(this);
|
|
1094
|
-
const executionStrategy = ExecutionStrategyFactory.create(this.mode);
|
|
1095
|
-
const result = await executionStrategy.execute(this, hook);
|
|
1096
|
-
hook.afterWorkflow(this, result);
|
|
1097
|
-
return result;
|
|
235
|
+
// src/domain/generative-model/generative-model.ts
|
|
236
|
+
var GenerativeModel = class {
|
|
237
|
+
async call(context) {
|
|
238
|
+
const request = this.mapContextToRequest(context);
|
|
239
|
+
const response = await this.infer(request);
|
|
240
|
+
return this.extractContextItems(response);
|
|
1098
241
|
}
|
|
1099
242
|
};
|
|
1100
243
|
|
|
1101
|
-
// src/
|
|
1102
|
-
var
|
|
1103
|
-
constructor(
|
|
244
|
+
// src/domain/context-runtime/input/function-call-output.ts
|
|
245
|
+
var FunctionCallOutput = class _FunctionCallOutput extends ContextItem {
|
|
246
|
+
constructor(callId, output) {
|
|
1104
247
|
super();
|
|
1105
|
-
this.
|
|
1106
|
-
this.
|
|
248
|
+
this.type = "function_call_output";
|
|
249
|
+
this.callId = callId;
|
|
250
|
+
this.output = output;
|
|
1107
251
|
}
|
|
1108
|
-
|
|
1109
|
-
return
|
|
252
|
+
static create(callId, output) {
|
|
253
|
+
return new _FunctionCallOutput(callId, output);
|
|
1110
254
|
}
|
|
1111
|
-
|
|
1112
|
-
return
|
|
255
|
+
static rehydrate(data) {
|
|
256
|
+
return new _FunctionCallOutput(data.callId, data.output);
|
|
1113
257
|
}
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
258
|
+
toJSON() {
|
|
259
|
+
return {
|
|
260
|
+
type: this.type,
|
|
261
|
+
callId: this.callId,
|
|
262
|
+
output: this.output.map((o) => o.toJSON())
|
|
1119
263
|
};
|
|
1120
|
-
const agent = new MozaikAgent(request);
|
|
1121
|
-
const result = await agent.act(this.task);
|
|
1122
|
-
hook.afterTask(this, result);
|
|
1123
|
-
return result;
|
|
1124
|
-
}
|
|
1125
|
-
};
|
|
1126
|
-
|
|
1127
|
-
// src/core/workflow/mapper.ts
|
|
1128
|
-
var PlanWorkflowMapper = class {
|
|
1129
|
-
static fromPlan(plan) {
|
|
1130
|
-
return this.fromNode(plan.root);
|
|
1131
|
-
}
|
|
1132
|
-
static fromNode(node) {
|
|
1133
|
-
if (node.kind !== "workflow") {
|
|
1134
|
-
throw new Error("Root must be workflow");
|
|
1135
|
-
}
|
|
1136
|
-
return new Workflow(node.mode, node.units.map(this.mapNode));
|
|
1137
|
-
}
|
|
1138
|
-
static mapNode(node) {
|
|
1139
|
-
if (node.kind === "task") {
|
|
1140
|
-
return new Task(node.task, node.model);
|
|
1141
|
-
}
|
|
1142
|
-
return new Workflow(node.mode, node.units.map(this.mapNode));
|
|
1143
|
-
}
|
|
1144
|
-
};
|
|
1145
|
-
|
|
1146
|
-
// src/core/agents/planner.ts
|
|
1147
|
-
var PROMPT = `You are a planner.
|
|
1148
|
-
|
|
1149
|
-
Rules:
|
|
1150
|
-
- Use 'parallel' for the task that can be run in parallel.
|
|
1151
|
-
- Pick model based on the task complexity
|
|
1152
|
-
- Keep prompts actionable.
|
|
1153
|
-
- Don't ask user for any input, just do the thing with available data you have.
|
|
1154
|
-
`;
|
|
1155
|
-
var PlanningAgent = class extends MozaikAgent {
|
|
1156
|
-
constructor(request) {
|
|
1157
|
-
super(request);
|
|
1158
|
-
}
|
|
1159
|
-
async planFromGoal(goal) {
|
|
1160
|
-
this.setStructuredOutput(PlanSchema);
|
|
1161
|
-
const response = await this.act(`${PROMPT}
|
|
1162
|
-
Goal: ${goal}`);
|
|
1163
|
-
const plan = response.data;
|
|
1164
|
-
return PlanWorkflowMapper.fromPlan(plan);
|
|
1165
264
|
}
|
|
1166
265
|
};
|
|
1167
266
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1168
267
|
0 && (module.exports = {
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
268
|
+
Context,
|
|
269
|
+
ContextItem,
|
|
270
|
+
DeveloperMessage,
|
|
271
|
+
FunctionCall,
|
|
272
|
+
FunctionCallOutput,
|
|
273
|
+
GenerativeModel,
|
|
274
|
+
ModelMessage,
|
|
275
|
+
Reasoning,
|
|
276
|
+
UserMessage
|
|
1175
277
|
});
|
|
1176
278
|
//# sourceMappingURL=index.js.map
|