@mozaik-ai/core 0.9.3 → 2.0.0

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