@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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Mozaik
2
2
 
3
- Mozaik is a TypeScript library for orchestrating AI agents, supporting both manually defined and AI-generated workflows.
3
+ Mozaik is a TypeScript library for orchestrating AI agents.
4
4
 
5
5
  ![mozaik](https://github.com/user-attachments/assets/0fdc15a8-3778-4d0e-bd13-143d04090b9e)
6
6
 
@@ -19,252 +19,89 @@ Make sure to set your API keys in a `.env` file at the root of your project:
19
19
  ```env
20
20
  # For OpenAI
21
21
  OPENAI_API_KEY=your-openai-key-here
22
-
23
- # For Anthropic Claude
24
- ANTHROPIC_API_KEY=your-anthropic-key-here
25
- ```
26
-
27
- ## Supported Models
28
-
29
- The system supports OpenAI models (gpt-5, gpt-5-mini, gpt-5-nano, gpt-5.1) and Anthropic Claude models (Claude Sonnet, Haiku, and Opus 4.5) out of the box.
30
-
31
- ---
32
-
33
- ## Features
34
-
35
- ### AI MozaikAgents
36
-
37
- This feature lets developers create AI agents through a single unified request definition, making it easy to compose tasks and leverage multiple models. You can mix providers, choose the best model for each task, and build agents that work across different capabilities.
38
-
39
- ```typescript
40
- import "dotenv/config"
41
- import { MozaikAgent, MozaikRequest } from "@mozaik-ai/core"
42
-
43
- const request: MozaikRequest = {
44
- model: "claude-sonnet-4.5",
45
- }
46
-
47
- const agent = new MozaikAgent(request)
48
- const codingResponse = await agent.act("Write a React component for a todo list")
49
- ```
50
-
51
- ### Structured Output
52
-
53
- Structured output lets you enforce exact response formats—using schemas like Zod—so AI returns predictable, validated data every time.
54
-
55
- ```typescript
56
- import { z } from "zod"
57
- import { MozaikAgent, MozaikRequest } from "@mozaik-ai/core"
58
-
59
- const mealPlanSchema = z.object({
60
- calories: z.number(),
61
- meals: z
62
- .array(
63
- z.object({
64
- name: z.string(),
65
- description: z.string(),
66
- ingredients: z.array(z.string()).min(3),
67
- }),
68
- )
69
- .length(3),
70
- shoppingList: z.array(z.string()),
71
- })
72
-
73
- const request: MozaikRequest = {
74
- model: "gpt-5-mini",
75
- task: "Create a 1-day vegetarian meal plan with breakfast, lunch, and dinner.",
76
- structuredOutput: mealPlanSchema,
77
- }
78
-
79
- const agent = new MozaikAgent(request)
80
- const response = await agent.act()
81
22
  ```
82
23
 
83
- ### Multi-turn Conversation
24
+ ## Context Runtime (Overview)
84
25
 
85
- Multi-turn conversation allows developers to provide chat history so the AI agent can maintain context and generate more relevant, continuous responses.
26
+ The **Context Runtime** models the core behavior of a language model:
86
27
 
87
- ```typescript
88
- import { MozaikAgent, MozaikRequest } from "@mozaik-ai/core"
28
+ > Given a structured **context**, produce a **response**.
89
29
 
90
- const request: MozaikRequest = {
91
- messages: [
92
- { role: "system", content: "You are a coding assistant" },
93
- { role: "user", content: "How do I sort an array in TypeScript?" },
94
- { role: "assistant", content: "You can use the .sort() method..." },
95
- ],
96
- model: "claude-haiku-4.5",
97
- }
98
-
99
- const agent = new MozaikAgent(request)
100
- const response = await agent.act("Can you show me an example?")
101
- ```
102
-
103
- ### Tool Calling
104
-
105
- Tool calling allows the agent to invoke real functions in your environment—letting it perform actual actions (like writing files, calling APIs, or modifying state) instead of merely generating text.
106
-
107
- ```typescript
108
- import { promises as fs } from "fs"
109
- import { MozaikAgent, MozaikRequest, Tool } from "@mozaik-ai/core"
110
-
111
- const tools: Tool[] = [
112
- {
113
- name: "write_file",
114
- description: "Write text to a file.",
115
- schema: {
116
- type: "object",
117
- properties: {
118
- filename: { type: "string" },
119
- content: { type: "string" },
120
- },
121
- required: ["filename", "content"],
122
- },
123
- async invoke({ filename, content }) {
124
- await fs.writeFile(filename, content, "utf8")
125
- return { ok: true }
126
- },
127
- },
128
- ]
129
-
130
- const request: MozaikRequest = {
131
- model: "gpt-5.1",
132
- tools,
133
- messages: [
134
- {
135
- role: "system",
136
- content: "Save notes to disk using the tool, then confirm where the file was written.",
137
- },
138
- ],
139
- task: "Create a two-bullet trip prep checklist for Belgrade and save it as trip-checklist.txt.",
140
- }
141
-
142
- const agent = new MozaikAgent(request)
143
- await agent.act()
144
- ```
30
+ It abstracts away vendor-specific APIs (e.g. OpenAI) and provides a domain-centric interface for working with LLMs.
145
31
 
146
- ### Vision
147
-
148
- Vision support allows AI agents to interpret images alongside text, enabling richer understanding and multimodal interactions.
149
-
150
- ```typescript
151
- import { MozaikAgent, MozaikRequest } from "@mozaik-ai/core"
152
-
153
- const request: MozaikRequest = {
154
- messages: [
155
- {
156
- role: "user",
157
- content: [
158
- {
159
- type: "image_url",
160
- url: "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
161
- },
162
- {
163
- type: "text",
164
- text: "What is in this image?",
165
- },
166
- ],
167
- },
168
- ],
169
- model: "claude-opus-4.5",
170
- }
171
-
172
- const agent = new MozaikAgent(request)
173
- const response = await agent.act()
174
- ```
175
-
176
- ### Parallel Task Execution
177
-
178
- This example demonstrates how to use standard JavaScript/TypeScript concurrency (Promise.all) to run multiple AI agents in parallel and compare or combine their responses.
179
-
180
- ```typescript
181
- import "dotenv/config"
182
- import { MozaikAgent, MozaikRequest } from "@mozaik-ai/core"
183
-
184
- const openaiRequest: MozaikRequest = {
185
- model: "gpt-5",
186
- }
187
-
188
- const anthropicRequest: MozaikRequest = {
189
- model: "claude-sonnet-4.5",
190
- }
32
+ ---
191
33
 
192
- const openaiAgent = new MozaikAgent(openaiRequest)
193
- const anthropicAgent = new MozaikAgent(anthropicRequest)
34
+ ## Compatibility
194
35
 
195
- const task = "What are the key differences between TypeScript and JavaScript?"
36
+ This domain model is fully compatible with the **Open Responses** specification for multi-provider LLM interfaces ([openresponses.org](https://www.openresponses.org/)).
196
37
 
197
- // Execute both agents in parallel using Promise.all()
198
- const [openaiResponse, anthropicResponse] = await Promise.all([openaiAgent.act(task), anthropicAgent.act(task)])
199
- ```
38
+ ![OpenResponses overview](public/openresponses-overview.png)
200
39
 
201
- ### Workflow
40
+ The core idea of OpenResponses is a **unified specification across LLM providers**: while vendors differ in details, most models follow the same interaction architecture and principles. OpenResponses standardizes that shared shape using **typed context items** (and clarifies that any item type can be streamed).
202
41
 
203
- A workflow defines how tasks are executed together, either sequentially (one after another) or in parallel. Each task or workflow is a `WorkUnit`, which allows workflows to be composed and nested to build more complex execution pipelines.
42
+ - **Input (context)**: client-provided context items such as **user_message**, **developer_message**, and **function_call_output**
43
+ - **Output (response)**: model-produced context items such as **reasoning**, **function_call**, and **model_message**
44
+ - **Streaming (optional)**: items may be delivered incrementally as **semantic events** (meaningful events at the item level, not just raw token streams)
204
45
 
205
- ```typescript
206
- const workflow = new Workflow("sequential", [
207
- new Task("Analyze requirements", "gpt-5"),
208
- new Workflow("parallel", [
209
- new Task("Generate API schema", "gpt-5-mini"),
210
- new Task("Draft documentation", "gpt-5-nano"),
211
- ]),
212
- new Task("Review and finalize", "gpt-5"),
213
- ])
46
+ ## Mozaik Core Concepts
214
47
 
215
- await workflow.execute()
216
- ```
48
+ Mozaik turns the OpenResponses specification into a practical **object model** so developers can manipulate LLM context in different ways (compose it, append model outputs, **persist it**, and **restore it** from a database/repository, etc.). This is a starting point—our main goal is to address core **context engineering** problems like **context bloating**, **context window overflow**, and **sequential agent collaboration**.
217
49
 
218
- ### AI Autonomy
50
+ ### Context
219
51
 
220
- Developers can create autonomous agents using an AI planner agent. The planner works as a meta-agent: it breaks a high-level goal into smaller tasks, assigns each task to a specialized agent, and coordinates their execution through a workflow.
52
+ Represents everything the model needs to generate a response.
221
53
 
222
- For example, given the goal `"Implement login functionality"`, the planner can generate the following workflow:
54
+ A context is composed of ordered **context items**.
223
55
 
224
- ```typescript
225
- Workflow(sequential, [
226
- Task("Design login form UI", "gpt-5"),
227
- Task("Implement authentication logic", "claude-sonnet-4.5"),
228
- Workflow(parallel, [Task("Add input validation", "gpt-5-mini"), Task("Style the login form", "gpt-5-nano")]),
229
- Task("Write unit tests", "gpt-5"),
230
- ])
231
- ```
56
+ ---
232
57
 
233
- ### Autonomy Slider
58
+ ### ContextItem
234
59
 
235
- By combining manually created workflows with the AI Planner, you can build hybrid workflows and control the level of autonomy, deciding which steps are fixed and which are planned automatically.
60
+ A single unit of context.
236
61
 
237
- ---
62
+ Examples:
238
63
 
239
- Working examples are available on the [GitHub repo](https://github.com/jigjoy-ai/mosaic-examples).
64
+ - Client-specific
65
+ - User message
66
+ - Developer message (System instruction)
67
+ - Function call output (added after a model function call and fed back so the model can continue reasoning or finish the job)
68
+ - Model-specific
69
+ - Function call
70
+ - Model message
71
+ - Reasoning
240
72
 
241
73
  ---
242
74
 
243
- ### Execution Hooks
244
-
245
- Execution hooks allow you to attach custom behavior to workflow and task execution without changing the workflow logic itself. Hooks are invoked at key lifecycle moments (before/after task or workflow execution) and are passed into `execute()`.
75
+ ## Example (Context + OpenAI Responses)
246
76
 
247
- A default hook cluster is provided out of the box, but you can extend or replace it to add logging, metrics, tracing, or other instrumentation.
77
+ This is a minimal end-to-end example that:
248
78
 
249
- #### Extending the default hooks
250
-
251
- You can add your own hooks by creating a new cluster or extending the default one:
79
+ - builds a `Context` from a developer message + user message
80
+ - calls a model (OpenAI Responses API)
81
+ - stores/restores the context using a repository
252
82
 
253
83
  ```ts
254
- import { ClusterHook } from "@core/workflow/hooks/cluster"
255
- import { DEFAULT_CLUSTER_HOOK } from "@core/workflow/hooks"
256
- import { MetricsHook } from "./metrics-hook"
84
+ const contextRepository = new InMemoryContextRepository()
257
85
 
258
- const extendedHook = new ClusterHook([DEFAULT_CLUSTER_HOOK, new MetricsHook()])
86
+ const message = UserMessage.create("Tell me a joke about birds")
87
+ const developerMessage = DeveloperMessage.create(
88
+ "You are a joke teller. You will be given a joke and you will need to tell it to the user.",
89
+ )
90
+ const projectId = `pr-${crypto.randomUUID()}`
91
+ const context = Context.create(projectId).addItem(developerMessage).addItem(message)
259
92
 
260
- await workflow.execute(extendedHook)
261
- ```
93
+ await contextRepository.save(context)
262
94
 
263
- If you’re building agentic systems and want to learn or connect with like-minded developers, join [our Discord](https://discord.gg/33uMhcerDU) where we share ideas and knowledge.
95
+ const model = new GPT54Model()
96
+ const newContextItems = await model.call(context)
97
+ context.addItems(newContextItems)
264
98
 
265
- ---
99
+ await contextRepository.save(context)
100
+ const restoredContexts = await contextRepository.getByProjectId(projectId)
101
+ console.log(restoredContexts)
102
+ ```
266
103
 
267
104
  ## Author & License
268
105
 
269
- Created by [JigJoy](https://jigjoy.io) team
106
+ Created by [JigJoy](https://jigjoy.io) team
270
107
  Licensed under the MIT License.
package/dist/index.d.mts CHANGED
@@ -1,132 +1,142 @@
1
- import { ZodObject } from 'zod';
2
-
3
- declare class Workflow extends WorkUnit {
4
- readonly mode: "parallel" | "sequential";
5
- readonly units: WorkUnit[];
6
- constructor(mode: "parallel" | "sequential", units: WorkUnit[]);
7
- execute(hook?: ExecutionHook): Promise<any>;
1
+ declare abstract class ContextItem {
2
+ abstract readonly type: string;
3
+ getType(): string;
4
+ abstract toJSON(): any;
8
5
  }
9
6
 
10
- declare class Task extends WorkUnit {
11
- private task;
12
- private model;
13
- constructor(task: string, model: Model);
14
- getTask(): string;
15
- getModel(): Model;
16
- execute(hook?: ExecutionHook): Promise<any>;
7
+ declare class Context {
8
+ readonly id: string;
9
+ readonly projectId: string;
10
+ readonly items: ContextItem[];
11
+ constructor(id: string, projectId: string, items: ContextItem[]);
12
+ addItem(item: ContextItem): Context;
13
+ addItems(items: ContextItem[]): Context;
14
+ getItems(): ContextItem[];
15
+ static create(projectId: string): Context;
16
+ static rehydrate(data: {
17
+ id: string;
18
+ projectId: string;
19
+ items: ContextItem[];
20
+ }): Context;
21
+ toJSON(): any;
17
22
  }
18
23
 
19
- interface ExecutionHook {
20
- beforeWorkflow(wf: Workflow): void;
21
- afterWorkflow(wf: Workflow, result: any): void;
22
- beforeTask(task: Task): void;
23
- afterTask(task: Task, result: any): void;
24
+ declare abstract class Content {
25
+ abstract readonly type: string;
24
26
  }
25
27
 
26
- declare abstract class WorkUnit {
27
- constructor();
28
- abstract execute(hook: ExecutionHook): Promise<any>;
28
+ declare class InputText extends Content {
29
+ readonly text: string;
30
+ readonly type = "input_text";
31
+ private constructor();
32
+ static create(text: string): InputText;
33
+ static rehydrate(data: {
34
+ text: string;
35
+ }): InputText;
36
+ toJSON(): any[];
29
37
  }
30
38
 
31
- interface TextPart {
32
- type: "text";
33
- text: string;
34
- }
35
- interface ImagePart {
36
- type: "image_url";
37
- url: string;
38
- }
39
- interface Message {
40
- role: "system" | "user" | "assistant" | "tool";
41
- content: string | Array<TextPart | ImagePart>;
39
+ declare class UserMessage extends ContextItem {
40
+ readonly type = "message";
41
+ readonly role = "user";
42
+ readonly content: InputText;
43
+ private constructor();
44
+ static create(text: string): UserMessage;
45
+ static rehydrate(data: {
46
+ text: string;
47
+ }): UserMessage;
48
+ toJSON(): any;
42
49
  }
43
50
 
44
- declare const OPENAI_MODELS: readonly ["gpt-5", "gpt-5-mini", "gpt-5-nano", "gpt-5.1", "gpt-5.2", "gpt-5.4"];
45
- type OpenAIModel = (typeof OPENAI_MODELS)[number];
46
- declare const ANTHROPIC_MODELS: readonly ["claude-sonnet-4.5", "claude-haiku-4.5", "claude-opus-4.5"];
47
- type AnthropicModel = (typeof ANTHROPIC_MODELS)[number];
48
- type Model = OpenAIModel | AnthropicModel;
49
-
50
- interface Tool {
51
- name: string;
52
- description: string;
53
- schema: Record<string, any>;
54
- invoke: (args: any) => Promise<any>;
51
+ declare class DeveloperMessage extends ContextItem {
52
+ readonly type = "message";
53
+ readonly role = "developer";
54
+ readonly content: InputText;
55
+ private constructor();
56
+ toJSON(): any;
57
+ static create(text: string): DeveloperMessage;
58
+ static rehydrate(data: {
59
+ text: string;
60
+ }): DeveloperMessage;
55
61
  }
56
62
 
57
- type MozaikRequest = {
58
- model: Model;
59
- messages?: Message[];
60
- task?: string;
61
- structuredOutput?: ZodObject<any>;
62
- tools?: Tool[];
63
- reasoningEffort?: ReasoningEffort;
64
- };
65
- declare enum ReasoningEffort {
66
- NONE = "none",
67
- LOW = "low",
68
- MEDIUM = "medium",
69
- HIGH = "high",
70
- MAX = "max"
63
+ declare class OutputText extends Content {
64
+ readonly text: string;
65
+ readonly type = "output_text";
66
+ private constructor();
67
+ static rehydrate(data: {
68
+ text: string;
69
+ }): OutputText;
70
+ toJSON(): any[];
71
71
  }
72
72
 
73
- declare abstract class RequestBuilder {
74
- request: any;
75
- initialize(): void;
76
- abstract addModel(model: string): RequestBuilder;
77
- abstract addTask(task: string): RequestBuilder;
78
- abstract addMessages(messages: Message[]): RequestBuilder;
79
- abstract addStructuredOutput(schema: ZodObject<any>): RequestBuilder;
80
- abstract addTools(tools: Tool[]): RequestBuilder;
81
- abstract addReasoningEffort(effort: ReasoningEffort): RequestBuilder;
82
- build(): any;
73
+ declare class ModelMessage extends ContextItem {
74
+ readonly type = "message";
75
+ readonly role = "assistant";
76
+ readonly content: OutputText;
77
+ private constructor();
78
+ static rehydrate(data: {
79
+ text: string;
80
+ }): ModelMessage;
81
+ toJSON(): any;
83
82
  }
84
83
 
85
- declare abstract class Endpoint {
86
- abstract requestBuilder: RequestBuilder;
87
- request: MozaikRequest | null;
88
- buildRequest(request: MozaikRequest): any;
89
- abstract sendRequest(providerRequest: any): any;
84
+ declare class FunctionCall extends ContextItem {
85
+ readonly type = "function_call";
86
+ readonly callId: string;
87
+ readonly name: string;
88
+ readonly args: string;
89
+ private constructor();
90
+ static rehydrate(data: {
91
+ callId: string;
92
+ name: string;
93
+ args: string;
94
+ }): FunctionCall;
95
+ toJSON(): any;
90
96
  }
91
97
 
92
- declare abstract class EndpointResolver {
93
- abstract resolve(model: string): Endpoint;
98
+ declare class SummaryText extends Content {
99
+ readonly text: string;
100
+ readonly type = "summary_text";
101
+ private constructor();
102
+ static rehydrate(data: {
103
+ text: string;
104
+ }): SummaryText;
105
+ toJSON(): Record<string, any>;
94
106
  }
95
107
 
96
- declare class RequestGateway {
97
- readonly endpointResolver: EndpointResolver;
98
- endpoint: Endpoint;
99
- constructor(endpointResolver: EndpointResolver);
100
- invoke(request: MozaikRequest): Promise<any>;
108
+ declare class Reasoning extends ContextItem {
109
+ readonly type = "reasoning";
110
+ readonly content: InputText | undefined;
111
+ readonly encryptedContent: string | undefined;
112
+ readonly summary: SummaryText[];
113
+ private constructor();
114
+ static rehydrate(data: {
115
+ content: InputText | undefined;
116
+ encryptedContent: string | undefined;
117
+ summary: SummaryText[];
118
+ }): Reasoning;
119
+ toJSON(): any;
101
120
  }
102
121
 
103
- declare class MozaikAgent {
104
- private request;
105
- gateway: RequestGateway;
106
- constructor(request: MozaikRequest);
107
- setModel(model: Model): void;
108
- setMessages(messages: Message[]): void;
109
- setTask(task: string): void;
110
- setStructuredOutput(schema: ZodObject<any>): void;
111
- act(task?: string): Promise<any>;
122
+ declare abstract class GenerativeModel {
123
+ abstract mapContextToRequest(context: Context): any[];
124
+ abstract extractContextItems(response: any): ContextItem[];
125
+ abstract infer(request: any): Promise<any>;
126
+ call(context: Context): Promise<ContextItem[]>;
112
127
  }
113
128
 
114
- declare class PlanningAgent extends MozaikAgent {
115
- constructor(request: MozaikRequest);
116
- planFromGoal(goal: string): Promise<Workflow>;
129
+ declare class FunctionCallOutput extends ContextItem {
130
+ readonly type = "function_call_output";
131
+ readonly callId: string;
132
+ readonly output: InputText[];
133
+ private constructor();
134
+ static create(callId: string, output: InputText[]): FunctionCallOutput;
135
+ static rehydrate(data: {
136
+ callId: string;
137
+ output: InputText[];
138
+ }): FunctionCallOutput;
139
+ toJSON(): any;
117
140
  }
118
141
 
119
- type UsageEntry = {
120
- inputTokens: number;
121
- outputTokens: number;
122
- model: string;
123
- };
124
- type MozaikResponse = {
125
- data: any;
126
- usage: {
127
- entries: UsageEntry[];
128
- totalUsdCost: number;
129
- };
130
- };
131
-
132
- export { type Message, type Model, MozaikAgent, type MozaikRequest, type MozaikResponse, PlanningAgent, Task, type Tool, WorkUnit, Workflow };
142
+ export { Context, ContextItem, DeveloperMessage, FunctionCall, FunctionCallOutput, GenerativeModel, ModelMessage, Reasoning, UserMessage };