@mozaik-ai/core 3.1.1 → 3.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +252 -63
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,24 +1,14 @@
1
1
  # Mozaik
2
2
 
3
- **Mozaik** is a TypeScript framework for building controllable multi-step AI agents.
3
+ **Mozaik** is a TypeScript framework for building non-blocking AI agents.
4
4
 
5
- Instead of focusing on agents themselves, Mozaik provides a structured way to **model, manipulate, persist, and restore the context** that drives language model behavior. It implements a clean object model aligned with the **OpenResponses specification**, enabling developers to work with LLM inputs and outputs as composable, typed entities.
6
-
7
- With Mozaik, you can:
8
-
9
- - Structure interactions as ordered **context items** (messages, reasoning steps, function calls, etc.)
10
- - Append and evolve context across multiple model calls
11
- - Persist and reload context from storage
12
- - Manage context size and avoid overflow
13
- - Build complex workflows through **context composition**, not ad-hoc prompt strings
14
-
15
- Mozaik treats context as a **first-class primitive**, making it easier to design scalable, maintainable, and provider-agnostic LLM applications.
5
+ It provides a structured agent loop, a lifecycle hook system, a typed context model, and an experimental multi-agent runtime — giving you full control over how agents think, act, and collaborate.
16
6
 
17
7
  ![mozaik](https://github.com/user-attachments/assets/0fdc15a8-3778-4d0e-bd13-143d04090b9e)
18
8
 
19
9
  ---
20
10
 
21
- ## 📦 Installation
11
+ ## Installation
22
12
 
23
13
  ```bash
24
14
  yarn add @mozaik-ai/core
@@ -26,94 +16,293 @@ yarn add @mozaik-ai/core
26
16
 
27
17
  ## API Key Configuration
28
18
 
29
- Make sure to set your API keys in a `.env` file at the root of your project:
30
-
31
19
  ```env
32
- # For OpenAI
20
+ # .env
33
21
  OPENAI_API_KEY=your-openai-key-here
34
22
  ```
35
23
 
36
- ## Context Runtime (Overview)
24
+ ---
25
+
26
+ ## Architecture
37
27
 
38
- The **Context Runtime** models the core behavior of a language model:
28
+ Mozaik is organized into four layers:
39
29
 
40
- > Given a structured **context**, produce a **response**.
30
+ ```mermaid
31
+ graph TD
32
+ AgentSociety["AgentSociety (experimental)"] --> Agent
33
+ Agent --> AgentRuntime
34
+ AgentRuntime --> AgentLoop["AgentLoop (FSM + hooks)"]
35
+ AgentLoop --> OpenAIResponses["OpenAIResponses (OpenResponses adapter)"]
36
+ AgentLoop --> Context["Context + ContextItems"]
37
+ ```
41
38
 
42
- It abstracts away vendor-specific APIs (e.g. OpenAI) and provides a domain-centric interface for working with LLMs.
39
+ | Layer | Responsibility |
40
+ | ----------------------- | ------------------------------------------------------ |
41
+ | **AgentSociety** | Runs multiple agents concurrently (experimental) |
42
+ | **Agent** | Lifecycle callbacks, visitor hooks, high-level `run()` |
43
+ | **AgentRuntime** | Drives the loop, dispatches hooks, manages errors |
44
+ | **AgentLoop + Context** | FSM transitions and typed context model |
43
45
 
44
46
  ---
45
47
 
46
- ## Compatibility
48
+ ## Core Concepts
47
49
 
48
- This domain model is fully compatible with the **Open Responses** specification for multi-provider LLM interfaces ([openresponses.org](https://www.openresponses.org/)).
50
+ ### Agent Loop
49
51
 
50
- ![OpenResponses overview](public/openresponses-overview.png)
52
+ The agent loop is a **finite state machine** that drives a multi-step inference cycle. Each execution moves through states until it reaches a terminal condition.
51
53
 
52
- 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).
54
+ ```mermaid
55
+ stateDiagram-v2
56
+ [*] --> INFERENCE_PENDING
57
+ INFERENCE_PENDING --> FUNCTION_CALL_PENDING: model returned a function call
58
+ INFERENCE_PENDING --> MODEL_MESSAGE_RECEIVED: model returned a message
59
+ FUNCTION_CALL_PENDING --> INFERENCE_PENDING: tool executed, feeding output back
60
+ MODEL_MESSAGE_RECEIVED --> [*]: execution complete
61
+ ```
53
62
 
54
- - **Input (context)**: client-provided context items such as **user_message**, **developer_message**, and **function_call_output**
55
- - **Output (response)**: model-produced context items such as **reasoning**, **function_call**, and **model_message**
56
- - **Streaming (optional)**: items may be delivered incrementally as **semantic events** (meaningful events at the item level, not just raw token streams)
63
+ An `Execution` object tracks the current state, step count, transition history, and terminal status (`RUNNING`, `COMPLETED`, `FAILED`).
57
64
 
58
- ## Mozaik Core Concepts
65
+ ---
59
66
 
60
- 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**.
67
+ ### Hooks (Events)
61
68
 
62
- ### Context
69
+ Every state transition exposes **before** and **after** hooks. You register callbacks on an `AgentRuntime` using `.on(hookId, callback)`:
63
70
 
64
- Represents everything the model needs to generate a response.
71
+ ```ts
72
+ import { AgentRuntime, HookId } from "@mozaik-ai/core"
65
73
 
66
- A context is composed of ordered **context items**.
74
+ const runtime = new AgentRuntime()
75
+
76
+ runtime.on(HookId.BEFORE_INFERENCE, async (context) => {
77
+ console.log("About to call the model...")
78
+ })
79
+
80
+ runtime.on(HookId.AFTER_INFERENCE, async (context) => {
81
+ console.log("Model responded:", context.inferenceResponse)
82
+ })
83
+
84
+ runtime.on(HookId.AFTER_FUNCTION_CALL, async (context) => {
85
+ console.log("Tool executed:", context.functionCallOutput)
86
+ })
87
+
88
+ runtime.on(HookId.ON_ERROR, async (context) => {
89
+ console.error("Agent failed:", context.error)
90
+ })
91
+ ```
92
+
93
+ Available hooks:
94
+
95
+ | Hook | Fires |
96
+ | ---------------------- | ------------------------------------ |
97
+ | `BEFORE_INFERENCE` | Before the model is called |
98
+ | `AFTER_INFERENCE` | After the model responds |
99
+ | `BEFORE_FUNCTION_CALL` | Before a tool is invoked |
100
+ | `AFTER_FUNCTION_CALL` | After a tool returns |
101
+ | `BEFORE_MODEL_MESSAGE` | Before the final message is received |
102
+ | `AFTER_MODEL_MESSAGE` | After the final message is received |
103
+ | `ON_ERROR` | When any state handler throws |
67
104
 
68
105
  ---
69
106
 
70
- ### ContextItem
107
+ ### Agent
71
108
 
72
- A single unit of context.
109
+ `Agent` wraps an `AgentRuntime` and pre-wires all hooks as overridable methods. Subclass it to customize behavior at any point in the lifecycle:
110
+
111
+ ```ts
112
+ import { Agent, AgentRuntime, RuntimeContext } from "@mozaik-ai/core"
73
113
 
74
- Examples:
114
+ class MyAgent extends Agent {
115
+ constructor() {
116
+ super(new AgentRuntime())
117
+ }
75
118
 
76
- - Client-specific
77
- - User message
78
- - Developer message (System instruction)
79
- - Function call output (added after a model function call and fed back so the model can continue reasoning or finish the job)
80
- - Model-specific
81
- - Function call
82
- - Model message
83
- - Reasoning
119
+ async afterInference(context: RuntimeContext): Promise<void> {
120
+ console.log("Tokens used:", context.inferenceResponse?.tokenUsage)
121
+ }
122
+
123
+ async onError(context: RuntimeContext): Promise<void> {
124
+ console.error("Something went wrong:", context.error?.message)
125
+ }
126
+ }
127
+
128
+ const agent = new MyAgent()
129
+ await agent.run("Summarize the latest news", model, context)
130
+ ```
131
+
132
+ ---
133
+
134
+ ### InferenceVisitor
135
+
136
+ `InferenceVisitor` is a **visitor interface** that lets you observe the inference lifecycle without modifying the agent itself. Attach it to any `Agent` instance via `setInferenceVisitor`.
137
+
138
+ ```ts
139
+ import { InferenceVisitor, InferenceResponse, RuntimeContext } from "@mozaik-ai/core"
140
+
141
+ class TelemetryVisitor implements InferenceVisitor {
142
+ async onStart(context: RuntimeContext): Promise<void> {
143
+ console.log("Agent started, execution:", context.execution.executionId)
144
+ }
145
+
146
+ async afterInference(response: InferenceResponse): Promise<void> {
147
+ console.log("Inference complete, tokens:", response.tokenUsage)
148
+ }
149
+ }
150
+
151
+ const agent = new MyAgent()
152
+ agent.setInferenceVisitor(new TelemetryVisitor())
153
+ ```
154
+
155
+ Use `InferenceVisitor` for concerns that should stay separate from agent logic: logging, telemetry, streaming responses to a UI, or recording usage metrics.
84
156
 
85
157
  ---
86
158
 
87
- ## Example (Context + OpenAI Responses)
159
+ ### Context Model
88
160
 
89
- This is a minimal end-to-end example that:
161
+ `Context` is the structured input passed to the model. It is composed of ordered **`ContextItem`** objects — each representing a single unit of context.
90
162
 
91
- - builds a `Context` from a developer message + user message
92
- - calls a model (OpenAI Responses API)
93
- - stores/restores the context using a repository
163
+ **Client-provided items** (you add these):
164
+
165
+ - `UserMessage` — the user's turn
166
+ - `DeveloperMessage` — system instructions
167
+ - `FunctionCallOutput` — tool result fed back to the model
168
+
169
+ **Model-produced items** (appended by the loop):
170
+
171
+ - `ModelMessage` — the model's final text response
172
+ - `FunctionCall` — a tool invocation requested by the model
173
+ - `Reasoning` — the model's internal reasoning trace
94
174
 
95
175
  ```ts
96
- const message = UserMessage.create("Tell me a joke about birds")
97
- const developerMessage = DeveloperMessage.create(
98
- "You are a joke teller. You will be given a joke and you will need to tell it to the user.",
99
- )
176
+ import { Context, DeveloperMessage, UserMessage, InMemoryContextRepository } from "@mozaik-ai/core"
100
177
 
101
- const projectId = `pr-${crypto.randomUUID()}`
102
- const contextRepository = new InMemoryContextRepository()
103
- const context = Context.create(projectId).addItem(developerMessage).addItem(message)
178
+ const context = Context.create("project-id")
179
+ .addItem(DeveloperMessage.create("You are a helpful assistant."))
180
+ .addItem(UserMessage.create("What is the capital of France?"))
104
181
 
105
- await contextRepository.save(context)
182
+ const repo = new InMemoryContextRepository()
183
+ await repo.save(context)
106
184
 
107
- const openresponses = new OpenAIResponses()
108
- const newContextItems = await openresponses.infer(gpt54, context)
109
- context.applyModelOutput(newContextItems)
185
+ // later...
186
+ const restored = await repo.getByProjectId("project-id")
187
+ ```
110
188
 
111
- await contextRepository.save(context)
112
- const restoredContexts = await contextRepository.getByProjectId(projectId)
113
- console.log(restoredContexts)
189
+ Context can be persisted and restored via `ContextRepository`. The built-in `InMemoryContextRepository` is suitable for development; implement `ContextRepository` to connect any storage backend.
190
+
191
+ ---
192
+
193
+ ### OpenResponses
194
+
195
+ `OpenAIResponses` is the framework's inference provider. It implements the **OpenResponses** specification ([openresponses.org](https://www.openresponses.org/)), mapping Mozaik's typed `Context` to the OpenAI Responses API and back.
196
+
197
+ It is the default provider used by `AgentRuntime` and handles:
198
+
199
+ - Serializing `ContextItem` objects to API-compatible input
200
+ - Deserializing model output into `ModelMessage`, `FunctionCall`, and `Reasoning` items
201
+ - Extracting token usage from the response
202
+
203
+ You can use it directly for single-shot inference outside the agent loop:
204
+
205
+ ```ts
206
+ import { OpenAIResponses, InferenceRequest, Gpt54 } from "@mozaik-ai/core"
207
+
208
+ const openaiResponses = new OpenAIResponses()
209
+ const request = new InferenceRequest(new Gpt54(), context)
210
+ const response = await openaiResponses.infer(request)
211
+
212
+ context.applyModelOutput(response.contextItems)
213
+ ```
214
+
215
+ Available models: `Gpt54`, `Gpt54Mini`, `Gpt54Nano`.
216
+
217
+ ---
218
+
219
+ ### AgentSociety _(experimental)_
220
+
221
+ `AgentSociety` is the framework's answer to one of the core limitations in today's agent systems: **agents that block on each other**. Most multi-agent frameworks run agents sequentially, which creates bottlenecks and prevents true parallelism.
222
+
223
+ `AgentSociety` runs agents **concurrently and non-blocking**. When `enter()` is called, every agent in the society starts its execution independently — none waits for another to finish.
224
+
225
+ ```ts
226
+ import { AgentSociety, AgentRuntime } from "@mozaik-ai/core"
227
+
228
+ const society = new AgentSociety("research-team")
229
+
230
+ society.join(new ResearchAgent())
231
+ society.join(new SummaryAgent())
232
+ society.join(new FactCheckAgent())
233
+
234
+ // Start the society's event loop
235
+ society.start()
236
+
237
+ // All three agents run in parallel on the same context
238
+ society.enter("Analyze the impact of AI on software development", model, context)
239
+
240
+ // Shut down when done
241
+ society.stop()
242
+ ```
243
+
244
+ All agents receive the same `Context`, enabling **collaborative context building** — each agent's output is visible to others through the shared context as the execution progresses.
245
+
246
+ > **Experimental:** `AgentSociety` is in active development. The API is stable enough to build on, but expect refinements — particularly around context isolation, coordination primitives, and agent-to-agent messaging. Feedback and contributions are welcome.
247
+
248
+ ---
249
+
250
+ ## Full Example
251
+
252
+ End-to-end example with a tool-calling agent and hook observability:
253
+
254
+ ```ts
255
+ import {
256
+ Agent,
257
+ AgentRuntime,
258
+ HookId,
259
+ Context,
260
+ DeveloperMessage,
261
+ Gpt54Mini,
262
+ InMemoryContextRepository,
263
+ Tool,
264
+ } from "@mozaik-ai/core"
265
+
266
+ // Define a tool
267
+ const weatherTool = new Tool({
268
+ name: "get_weather",
269
+ description: "Get the current weather for a city",
270
+ parameters: {
271
+ type: "object",
272
+ properties: { city: { type: "string" } },
273
+ required: ["city"],
274
+ },
275
+ invoke: async ({ city }) => ({ temperature: "22°C", condition: "sunny" }),
276
+ })
277
+
278
+ // Create runtime and wire hooks
279
+ const runtime = new AgentRuntime()
280
+
281
+ runtime.on(HookId.BEFORE_INFERENCE, async (ctx) => {
282
+ console.log(`[step ${ctx.execution.stepCount}] calling model...`)
283
+ })
284
+
285
+ runtime.on(HookId.AFTER_FUNCTION_CALL, async (ctx) => {
286
+ console.log("tool result:", ctx.functionCallOutput)
287
+ })
288
+
289
+ // Create agent
290
+ const agent = new Agent(runtime)
291
+
292
+ // Set up model and context
293
+ const model = new Gpt54Mini([weatherTool])
294
+ const context = Context.create("demo").addItem(DeveloperMessage.create("You are a weather assistant."))
295
+
296
+ const repo = new InMemoryContextRepository()
297
+ await repo.save(context)
298
+
299
+ // Run
300
+ await agent.run("What's the weather like in Tokyo?", model, context)
114
301
  ```
115
302
 
303
+ ---
304
+
116
305
  ## Author & License
117
306
 
118
- Created by [JigJoy](https://jigjoy.io) team
307
+ Created by the [JigJoy](https://jigjoy.io) team.
119
308
  Licensed under the MIT License.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mozaik-ai/core",
3
- "version": "3.1.1",
3
+ "version": "3.1.2",
4
4
  "description": "A TypeScript framework for building AI agents",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",