@mastra/inngest 1.2.2 → 1.3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,229 @@
1
1
  # @mastra/inngest
2
2
 
3
+ ## 1.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Add durable agents with resumable streams ([#12557](https://github.com/mastra-ai/mastra/pull/12557))
8
+
9
+ Durable agents make agent execution resilient to disconnections, crashes, and long-running operations.
10
+
11
+ ### The Problem
12
+
13
+ Standard agent streaming has two fragility points:
14
+ 1. **Connection drops** - If a client disconnects mid-stream (network blip, browser refresh, mobile app backgrounded), all subsequent events are lost. The client has no way to "catch up" on what they missed.
15
+ 2. **Long-running operations** - Agent loops with tool calls can take minutes. Holding an HTTP connection open that long is unreliable. If the server restarts or the connection times out, the work is lost.
16
+
17
+ ### The Solution
18
+
19
+ **Resumable streams** solve connection drops. Every event is cached with a sequential index. If a client disconnects at event 5, they can reconnect and request events starting from index 6. They receive cached events immediately, then continue with live events as they arrive.
20
+
21
+ **Durable execution** solves long-running operations. Instead of executing the agent loop directly in the HTTP request, execution happens in a workflow engine (built-in evented engine or Inngest). The HTTP request just subscribes to events. If the connection drops, execution continues. The client can reconnect anytime to observe progress.
22
+
23
+ ### Usage
24
+
25
+ Wrap any existing `Agent` with durability using factory functions:
26
+
27
+ ```typescript
28
+ import { Agent } from '@mastra/core/agent';
29
+ import { createDurableAgent } from '@mastra/core/agent/durable';
30
+
31
+ const agent = new Agent({
32
+ id: 'my-agent',
33
+ model: openai('gpt-4'),
34
+ instructions: 'You are helpful',
35
+ });
36
+
37
+ const durableAgent = createDurableAgent({ agent });
38
+ ```
39
+
40
+ **Factory functions for different execution strategies:**
41
+
42
+ | Factory | Execution | Use Case |
43
+ | ---------------------------------------- | ----------------------------------- | ------------------------------- |
44
+ | `createDurableAgent({ agent })` | Local, synchronous | Development, simple deployments |
45
+ | `createEventedAgent({ agent })` | Fire-and-forget via workflow engine | Long-running operations |
46
+ | `createInngestAgent({ agent, inngest })` | Inngest-powered | Production, distributed systems |
47
+
48
+ ### Resumable Streams
49
+
50
+ ```typescript
51
+ // Start streaming
52
+ const { runId, output } = await durableAgent.stream('Analyze this data...');
53
+
54
+ // Client disconnects at event 5...
55
+
56
+ // Reconnect and resume from where we left off
57
+ const { output: resumed } = await durableAgent.observe(runId, { offset: 6 });
58
+ // Receives events 6, 7, 8... from cache, then continues with live events
59
+ ```
60
+
61
+ ### PubSub and Cache
62
+
63
+ Durable agents use two infrastructure components:
64
+
65
+ | Component | Purpose | Default |
66
+ | ---------- | ----------------------------------------- | --------------------- |
67
+ | **PubSub** | Real-time event delivery during streaming | `EventEmitterPubSub` |
68
+ | **Cache** | Stores events for replay on reconnection | `InMemoryServerCache` |
69
+
70
+ When `stream()` is called, events flow through pubsub in real-time. The cache stores each event with a sequential index. When `observe()` is called, missed events replay from cache before continuing with live events.
71
+
72
+ **Configure via Mastra instance (recommended):**
73
+
74
+ ```typescript
75
+ const mastra = new Mastra({
76
+ cache: new RedisServerCache({ url: 'redis://...' }),
77
+ pubsub: new RedisPubSub({ url: 'redis://...' }),
78
+ agents: {
79
+ // Inherits cache and pubsub from Mastra
80
+ myAgent: createDurableAgent({ agent }),
81
+ },
82
+ });
83
+ ```
84
+
85
+ **Configure per-agent (overrides Mastra):**
86
+
87
+ ```typescript
88
+ const durableAgent = createDurableAgent({
89
+ agent,
90
+ cache: new RedisServerCache({ url: 'redis://...' }),
91
+ pubsub: new RedisPubSub({ url: 'redis://...' }),
92
+ });
93
+ ```
94
+
95
+ **Disable caching (streams won't be resumable):**
96
+
97
+ ```typescript
98
+ const durableAgent = createDurableAgent({ agent, cache: false });
99
+ ```
100
+
101
+ For single-instance deployments, the defaults work fine. For multi-instance deployments (load balancer, horizontal scaling), use Redis-backed implementations so any instance can serve reconnection requests.
102
+
103
+ ### Class Hierarchy
104
+ - `DurableAgent` extends `Agent` - base class with resumable streams
105
+ - `EventedAgent` extends `DurableAgent` - fire-and-forget execution
106
+ - `InngestAgent` extends `DurableAgent` - Inngest-powered execution
107
+
108
+ - Update peer dependencies to match core package version bump (1.0.5) ([#12557](https://github.com/mastra-ai/mastra/pull/12557))
109
+
110
+ ### Patch Changes
111
+
112
+ - Updated dependencies [[`920c757`](https://github.com/mastra-ai/mastra/commit/920c75799c6bd71787d86deaf654a35af4c839ca), [`d587199`](https://github.com/mastra-ai/mastra/commit/d5871993c0371bde2b0717d6b47194755baa1443), [`1fe2533`](https://github.com/mastra-ai/mastra/commit/1fe2533c4382ca6858aac7c4b63e888c2eac6541), [`f8694b6`](https://github.com/mastra-ai/mastra/commit/f8694b6fa0b7a5cde71d794c3bbef4957c55bcb8)]:
113
+ - @mastra/core@1.30.0
114
+
115
+ ## 1.3.0-alpha.0
116
+
117
+ ### Minor Changes
118
+
119
+ - Add durable agents with resumable streams ([#12557](https://github.com/mastra-ai/mastra/pull/12557))
120
+
121
+ Durable agents make agent execution resilient to disconnections, crashes, and long-running operations.
122
+
123
+ ### The Problem
124
+
125
+ Standard agent streaming has two fragility points:
126
+ 1. **Connection drops** - If a client disconnects mid-stream (network blip, browser refresh, mobile app backgrounded), all subsequent events are lost. The client has no way to "catch up" on what they missed.
127
+ 2. **Long-running operations** - Agent loops with tool calls can take minutes. Holding an HTTP connection open that long is unreliable. If the server restarts or the connection times out, the work is lost.
128
+
129
+ ### The Solution
130
+
131
+ **Resumable streams** solve connection drops. Every event is cached with a sequential index. If a client disconnects at event 5, they can reconnect and request events starting from index 6. They receive cached events immediately, then continue with live events as they arrive.
132
+
133
+ **Durable execution** solves long-running operations. Instead of executing the agent loop directly in the HTTP request, execution happens in a workflow engine (built-in evented engine or Inngest). The HTTP request just subscribes to events. If the connection drops, execution continues. The client can reconnect anytime to observe progress.
134
+
135
+ ### Usage
136
+
137
+ Wrap any existing `Agent` with durability using factory functions:
138
+
139
+ ```typescript
140
+ import { Agent } from '@mastra/core/agent';
141
+ import { createDurableAgent } from '@mastra/core/agent/durable';
142
+
143
+ const agent = new Agent({
144
+ id: 'my-agent',
145
+ model: openai('gpt-4'),
146
+ instructions: 'You are helpful',
147
+ });
148
+
149
+ const durableAgent = createDurableAgent({ agent });
150
+ ```
151
+
152
+ **Factory functions for different execution strategies:**
153
+
154
+ | Factory | Execution | Use Case |
155
+ | ---------------------------------------- | ----------------------------------- | ------------------------------- |
156
+ | `createDurableAgent({ agent })` | Local, synchronous | Development, simple deployments |
157
+ | `createEventedAgent({ agent })` | Fire-and-forget via workflow engine | Long-running operations |
158
+ | `createInngestAgent({ agent, inngest })` | Inngest-powered | Production, distributed systems |
159
+
160
+ ### Resumable Streams
161
+
162
+ ```typescript
163
+ // Start streaming
164
+ const { runId, output } = await durableAgent.stream('Analyze this data...');
165
+
166
+ // Client disconnects at event 5...
167
+
168
+ // Reconnect and resume from where we left off
169
+ const { output: resumed } = await durableAgent.observe(runId, { offset: 6 });
170
+ // Receives events 6, 7, 8... from cache, then continues with live events
171
+ ```
172
+
173
+ ### PubSub and Cache
174
+
175
+ Durable agents use two infrastructure components:
176
+
177
+ | Component | Purpose | Default |
178
+ | ---------- | ----------------------------------------- | --------------------- |
179
+ | **PubSub** | Real-time event delivery during streaming | `EventEmitterPubSub` |
180
+ | **Cache** | Stores events for replay on reconnection | `InMemoryServerCache` |
181
+
182
+ When `stream()` is called, events flow through pubsub in real-time. The cache stores each event with a sequential index. When `observe()` is called, missed events replay from cache before continuing with live events.
183
+
184
+ **Configure via Mastra instance (recommended):**
185
+
186
+ ```typescript
187
+ const mastra = new Mastra({
188
+ cache: new RedisServerCache({ url: 'redis://...' }),
189
+ pubsub: new RedisPubSub({ url: 'redis://...' }),
190
+ agents: {
191
+ // Inherits cache and pubsub from Mastra
192
+ myAgent: createDurableAgent({ agent }),
193
+ },
194
+ });
195
+ ```
196
+
197
+ **Configure per-agent (overrides Mastra):**
198
+
199
+ ```typescript
200
+ const durableAgent = createDurableAgent({
201
+ agent,
202
+ cache: new RedisServerCache({ url: 'redis://...' }),
203
+ pubsub: new RedisPubSub({ url: 'redis://...' }),
204
+ });
205
+ ```
206
+
207
+ **Disable caching (streams won't be resumable):**
208
+
209
+ ```typescript
210
+ const durableAgent = createDurableAgent({ agent, cache: false });
211
+ ```
212
+
213
+ For single-instance deployments, the defaults work fine. For multi-instance deployments (load balancer, horizontal scaling), use Redis-backed implementations so any instance can serve reconnection requests.
214
+
215
+ ### Class Hierarchy
216
+ - `DurableAgent` extends `Agent` - base class with resumable streams
217
+ - `EventedAgent` extends `DurableAgent` - fire-and-forget execution
218
+ - `InngestAgent` extends `DurableAgent` - Inngest-powered execution
219
+
220
+ - Update peer dependencies to match core package version bump (1.0.5) ([#12557](https://github.com/mastra-ai/mastra/pull/12557))
221
+
222
+ ### Patch Changes
223
+
224
+ - Updated dependencies [[`920c757`](https://github.com/mastra-ai/mastra/commit/920c75799c6bd71787d86deaf654a35af4c839ca), [`1fe2533`](https://github.com/mastra-ai/mastra/commit/1fe2533c4382ca6858aac7c4b63e888c2eac6541), [`f8694b6`](https://github.com/mastra-ai/mastra/commit/f8694b6fa0b7a5cde71d794c3bbef4957c55bcb8)]:
225
+ - @mastra/core@1.30.0-alpha.1
226
+
3
227
  ## 1.2.2
4
228
 
5
229
  ### Patch Changes
@@ -1,8 +1,8 @@
1
1
  import { Mastra } from '@mastra/core/mastra';
2
2
  import { Inngest } from 'inngest';
3
3
  import type { InngestWorkflow } from '../../workflow.js';
4
- export declare const INNGEST_PORT = 4000;
5
- export declare const HANDLER_PORT = 4001;
4
+ export declare const INNGEST_PORT = 4100;
5
+ export declare const HANDLER_PORT = 4101;
6
6
  export declare function createTestInngest(id: string): Inngest<{
7
7
  id: string;
8
8
  baseUrl: string;
@@ -0,0 +1,43 @@
1
+ import { Mastra } from '@mastra/core/mastra';
2
+ import { Inngest } from 'inngest';
3
+ export declare const INNGEST_PORT = 4100;
4
+ export declare const HANDLER_PORT = 4101;
5
+ /**
6
+ * Generate unique test ID to isolate each test.
7
+ * Uses a short UUID for readability in logs.
8
+ */
9
+ export declare function generateTestId(): string;
10
+ /**
11
+ * Get the shared Inngest client.
12
+ * All tests use the same Inngest client since workflow state is isolated by runId/agentId.
13
+ */
14
+ export declare function getSharedInngest(): Inngest;
15
+ /**
16
+ * Get the shared Mastra instance.
17
+ * @throws Error if called before setupSharedTestInfrastructure()
18
+ */
19
+ export declare function getSharedMastra(): Mastra;
20
+ /**
21
+ * Wait for Inngest to sync with the app.
22
+ */
23
+ export declare function waitForInngestSync(ms?: number): Promise<void>;
24
+ /**
25
+ * Initialize shared test infrastructure.
26
+ * Call this once in beforeAll for the test suite.
27
+ *
28
+ * This starts the Inngest dev server using npx (no Docker required).
29
+ */
30
+ export declare function setupSharedTestInfrastructure(): Promise<void>;
31
+ /**
32
+ * Teardown shared test infrastructure.
33
+ * Call this once in afterAll for the test suite.
34
+ */
35
+ export declare function teardownSharedTestInfrastructure(): Promise<void>;
36
+ /**
37
+ * Test setup result containing everything needed to run a test.
38
+ */
39
+ export interface TestSetup {
40
+ mastra: Mastra;
41
+ cleanup: () => Promise<void>;
42
+ }
43
+ //# sourceMappingURL=durable-agent.test.utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"durable-agent.test.utils.d.ts","sourceRoot":"","sources":["../../src/__tests__/durable-agent.test.utils.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG7C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAIlC,eAAO,MAAM,YAAY,OAAO,CAAC;AACjC,eAAO,MAAM,YAAY,OAAO,CAAC;AAYjC;;;GAGG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAS1C;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAKxC;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,EAAE,SAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhE;AAqFD;;;;;GAKG;AACH,wBAAsB,6BAA6B,IAAI,OAAO,CAAC,IAAI,CAAC,CAmDnE;AAED;;;GAGG;AACH,wBAAsB,gCAAgC,IAAI,OAAO,CAAC,IAAI,CAAC,CAuBtE;AAMD;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B"}
@@ -0,0 +1,300 @@
1
+ /**
2
+ * Factory function to create an Inngest-powered durable agent.
3
+ *
4
+ * This provides a clean API for wrapping a Mastra Agent with Inngest's
5
+ * durable execution engine. The returned object can be registered with
6
+ * Mastra like any other agent, and the required workflow is automatically
7
+ * registered when added to Mastra.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { Agent } from '@mastra/core/agent';
12
+ * import { createInngestAgent } from '@mastra/inngest';
13
+ * import { Inngest } from 'inngest';
14
+ * import { realtimeMiddleware } from '@inngest/realtime/middleware';
15
+ *
16
+ * const inngest = new Inngest({
17
+ * id: 'my-app',
18
+ * middleware: [realtimeMiddleware()],
19
+ * });
20
+ *
21
+ * const agent = new Agent({
22
+ * id: 'my-agent',
23
+ * name: 'My Agent',
24
+ * instructions: 'You are a helpful assistant',
25
+ * model: openai('gpt-4'),
26
+ * });
27
+ *
28
+ * const durableAgent = createInngestAgent({ agent, inngest });
29
+ *
30
+ * const mastra = new Mastra({
31
+ * agents: { myAgent: durableAgent },
32
+ * });
33
+ *
34
+ * // Use the agent
35
+ * const { output, cleanup } = await durableAgent.stream('Hello!');
36
+ * const text = await output.text;
37
+ * cleanup();
38
+ * ```
39
+ */
40
+ import type { Agent, AgentExecutionOptions } from '@mastra/core/agent';
41
+ import type { AgentFinishEventData, AgentStepFinishEventData, AgentSuspendedEventData } from '@mastra/core/agent/durable';
42
+ import type { MessageListInput } from '@mastra/core/agent/message-list';
43
+ import type { MastraServerCache } from '@mastra/core/cache';
44
+ import type { PubSub } from '@mastra/core/events';
45
+ import type { Mastra } from '@mastra/core/mastra';
46
+ import type { MastraModelOutput, ChunkType } from '@mastra/core/stream';
47
+ import type { Workflow } from '@mastra/core/workflows';
48
+ import type { Inngest } from 'inngest';
49
+ /**
50
+ * Options for createInngestAgent factory function.
51
+ */
52
+ export interface CreateInngestAgentOptions {
53
+ /** The Mastra Agent to wrap with durable execution */
54
+ agent: Agent<any, any, any>;
55
+ /** Inngest client instance */
56
+ inngest: Inngest;
57
+ /** Optional ID override (defaults to agent.id) */
58
+ id?: string;
59
+ /** Optional name override (defaults to agent.name) */
60
+ name?: string;
61
+ /** Optional PubSub override (defaults to InngestPubSub) */
62
+ pubsub?: PubSub;
63
+ /**
64
+ * Cache instance for storing stream events.
65
+ * Enables resumable streams - clients can disconnect and reconnect
66
+ * without missing events.
67
+ *
68
+ * When provided, the pubsub is wrapped with CachingPubSub.
69
+ */
70
+ cache?: MastraServerCache;
71
+ /** Mastra instance for observability (optional, set automatically when registered with Mastra) */
72
+ mastra?: Mastra;
73
+ }
74
+ /**
75
+ * Options for InngestAgent.stream()
76
+ */
77
+ export interface InngestAgentStreamOptions<OUTPUT = undefined> {
78
+ /** Custom instructions that override the agent's default instructions */
79
+ instructions?: AgentExecutionOptions<OUTPUT>['instructions'];
80
+ /** Additional context messages */
81
+ context?: AgentExecutionOptions<OUTPUT>['context'];
82
+ /** Memory configuration */
83
+ memory?: AgentExecutionOptions<OUTPUT>['memory'];
84
+ /** Unique identifier for this execution run */
85
+ runId?: string;
86
+ /** Request Context */
87
+ requestContext?: AgentExecutionOptions<OUTPUT>['requestContext'];
88
+ /** Maximum number of steps */
89
+ maxSteps?: number;
90
+ /** Additional tool sets */
91
+ toolsets?: AgentExecutionOptions<OUTPUT>['toolsets'];
92
+ /** Client-side tools */
93
+ clientTools?: AgentExecutionOptions<OUTPUT>['clientTools'];
94
+ /** Tool selection strategy */
95
+ toolChoice?: AgentExecutionOptions<OUTPUT>['toolChoice'];
96
+ /** Model settings */
97
+ modelSettings?: AgentExecutionOptions<OUTPUT>['modelSettings'];
98
+ /** Require approval for all tool calls */
99
+ requireToolApproval?: boolean;
100
+ /** Automatically resume suspended tools */
101
+ autoResumeSuspendedTools?: boolean;
102
+ /** Maximum concurrent tool calls */
103
+ toolCallConcurrency?: number;
104
+ /** Include raw chunks in output */
105
+ includeRawChunks?: boolean;
106
+ /** Maximum processor retries */
107
+ maxProcessorRetries?: number;
108
+ /** Callback when chunk is received */
109
+ onChunk?: (chunk: ChunkType<OUTPUT>) => void | Promise<void>;
110
+ /** Callback when step finishes */
111
+ onStepFinish?: (result: AgentStepFinishEventData) => void | Promise<void>;
112
+ /** Callback when execution finishes */
113
+ onFinish?: (result: AgentFinishEventData) => void | Promise<void>;
114
+ /** Callback on error */
115
+ onError?: (error: Error) => void | Promise<void>;
116
+ /** Callback when workflow suspends */
117
+ onSuspended?: (data: AgentSuspendedEventData) => void | Promise<void>;
118
+ }
119
+ /**
120
+ * Result from InngestAgent.stream()
121
+ */
122
+ export interface InngestAgentStreamResult<OUTPUT = undefined> {
123
+ /** The streaming output */
124
+ output: MastraModelOutput<OUTPUT>;
125
+ /** The full stream - delegates to output.fullStream for server compatibility */
126
+ readonly fullStream: ReadableStream<any>;
127
+ /** The unique run ID */
128
+ runId: string;
129
+ /** Thread ID if using memory */
130
+ threadId?: string;
131
+ /** Resource ID if using memory */
132
+ resourceId?: string;
133
+ /** Cleanup function */
134
+ cleanup: () => void;
135
+ }
136
+ /**
137
+ * An Inngest-powered durable agent.
138
+ *
139
+ * This interface represents an agent that uses Inngest's durable execution engine.
140
+ * It can be registered with Mastra like a regular Agent, and the required workflow
141
+ * is automatically registered.
142
+ *
143
+ * At runtime, a Proxy forwards all Agent method calls (e.g., `generate()`, `listTools()`,
144
+ * `getMemory()`) to the underlying agent. The index signature below reflects this:
145
+ * any property not explicitly declared here is available via the Proxy.
146
+ */
147
+ export interface InngestAgent<TOutput = undefined> {
148
+ /** Agent ID */
149
+ readonly id: string;
150
+ /** Agent name */
151
+ readonly name: string;
152
+ /** The underlying Mastra Agent (for Mastra registration) */
153
+ readonly agent: Agent<any, any, TOutput>;
154
+ /** The Inngest client */
155
+ readonly inngest: Inngest;
156
+ /** The cache instance if resumable streams are enabled */
157
+ readonly cache?: MastraServerCache;
158
+ /**
159
+ * The PubSub instance used for streaming events.
160
+ * Returns the CachingPubSub wrapper if caching is enabled.
161
+ * @internal Used by the server's observe endpoint to subscribe to the correct PubSub instance.
162
+ */
163
+ readonly pubsub: PubSub;
164
+ /**
165
+ * Stream a response using Inngest's durable execution.
166
+ */
167
+ stream(messages: MessageListInput, options?: InngestAgentStreamOptions<TOutput>): Promise<InngestAgentStreamResult<TOutput>>;
168
+ /**
169
+ * Resume a suspended workflow execution.
170
+ */
171
+ resume(runId: string, resumeData: unknown, options?: {
172
+ threadId?: string;
173
+ resourceId?: string;
174
+ onChunk?: (chunk: ChunkType<TOutput>) => void | Promise<void>;
175
+ onStepFinish?: (result: AgentStepFinishEventData) => void | Promise<void>;
176
+ onFinish?: (result: AgentFinishEventData) => void | Promise<void>;
177
+ onError?: (error: Error) => void | Promise<void>;
178
+ onSuspended?: (data: AgentSuspendedEventData) => void | Promise<void>;
179
+ }): Promise<InngestAgentStreamResult<TOutput>>;
180
+ /**
181
+ * Prepare for durable execution without starting it.
182
+ */
183
+ prepare(messages: MessageListInput, options?: AgentExecutionOptions<TOutput>): Promise<{
184
+ runId: string;
185
+ messageId: string;
186
+ workflowInput: any;
187
+ threadId?: string;
188
+ resourceId?: string;
189
+ }>;
190
+ /**
191
+ * Observe (reconnect to) an existing stream.
192
+ * Use this to resume receiving events after a disconnection.
193
+ *
194
+ * @param runId - The run ID to observe
195
+ * @param options.offset - Resume from this event index (0-based). If omitted, replays all events.
196
+ */
197
+ observe(runId: string, options?: {
198
+ offset?: number;
199
+ onChunk?: (chunk: ChunkType<TOutput>) => void | Promise<void>;
200
+ onStepFinish?: (result: AgentStepFinishEventData) => void | Promise<void>;
201
+ onFinish?: (result: AgentFinishEventData) => void | Promise<void>;
202
+ onError?: (error: Error) => void | Promise<void>;
203
+ onSuspended?: (data: AgentSuspendedEventData) => void | Promise<void>;
204
+ }): Promise<Omit<InngestAgentStreamResult<TOutput>, 'threadId' | 'resourceId'> & {
205
+ runId: string;
206
+ }>;
207
+ /**
208
+ * Get the durable workflows required by this agent.
209
+ * Called by Mastra during agent registration.
210
+ * @internal
211
+ */
212
+ getDurableWorkflows(): Workflow<any, any, any, any, any, any, any>[];
213
+ /**
214
+ * Set the Mastra instance for observability.
215
+ * Called by Mastra during agent registration.
216
+ * @internal
217
+ */
218
+ __setMastra(mastra: Mastra): void;
219
+ /** Generate a non-streaming response. Forwarded to the underlying Agent. */
220
+ generate(messages: MessageListInput, options?: AgentExecutionOptions<any>): Promise<any>;
221
+ /** Get the agent's description. Forwarded to the underlying Agent. */
222
+ getDescription(): string;
223
+ /** Get the agent's instructions. Forwarded to the underlying Agent. */
224
+ getInstructions(...args: any[]): any;
225
+ /** List tools available to the agent. Forwarded to the underlying Agent. */
226
+ listTools(...args: any[]): any;
227
+ /** Get the agent's LLM configuration. Forwarded to the underlying Agent. */
228
+ getLLM(...args: any[]): any;
229
+ /** Get the agent's model. Forwarded to the underlying Agent. */
230
+ getModel(...args: any[]): any;
231
+ /** Get the agent's memory instance. Forwarded to the underlying Agent. */
232
+ getMemory(...args: any[]): any;
233
+ /** Check if agent has its own memory. Forwarded to the underlying Agent. */
234
+ hasOwnMemory(): boolean;
235
+ /** Get the agent's workspace. Forwarded to the underlying Agent. */
236
+ getWorkspace(...args: any[]): any;
237
+ /** List sub-agents. Forwarded to the underlying Agent. */
238
+ listAgents(...args: any[]): any;
239
+ /** List workflows. Forwarded to the underlying Agent. */
240
+ listWorkflows(...args: any[]): any;
241
+ /** Get default execution options. Forwarded to the underlying Agent. */
242
+ getDefaultOptions(...args: any[]): any;
243
+ /** Get legacy generate options. Forwarded to the underlying Agent. */
244
+ getDefaultGenerateOptionsLegacy(...args: any[]): any;
245
+ /** Get legacy stream options. Forwarded to the underlying Agent. */
246
+ getDefaultStreamOptionsLegacy(...args: any[]): any;
247
+ /** Get available models. Forwarded to the underlying Agent. */
248
+ getModelList(...args: any[]): any;
249
+ /** Get configured processor workflows. Forwarded to the underlying Agent. */
250
+ getConfiguredProcessorWorkflows(...args: any[]): any;
251
+ /** Get raw agent configuration. Forwarded to the underlying Agent. */
252
+ toRawConfig(...args: any[]): any;
253
+ /** Resume a streaming execution. Forwarded to the underlying Agent. */
254
+ resumeStream(...args: any[]): any;
255
+ /** Resume a generate execution. Forwarded to the underlying Agent. */
256
+ resumeGenerate(...args: any[]): any;
257
+ /** Approve a pending tool call. Forwarded to the underlying Agent. */
258
+ approveToolCall(...args: any[]): any;
259
+ /** @internal Update the agent's model. Forwarded to the underlying Agent. */
260
+ __updateModel(...args: any[]): any;
261
+ /** @internal Reset to original model. Forwarded to the underlying Agent. */
262
+ __resetToOriginalModel(...args: any[]): any;
263
+ /** @internal Set logger. Forwarded to the underlying Agent. */
264
+ __setLogger(...args: any[]): any;
265
+ /** @internal Register primitives. Forwarded to the underlying Agent. */
266
+ __registerPrimitives(...args: any[]): any;
267
+ /** @internal Register Mastra instance. Forwarded to the underlying Agent. */
268
+ __registerMastra(...args: any[]): any;
269
+ }
270
+ /**
271
+ * Create an Inngest-powered durable agent from a Mastra Agent.
272
+ *
273
+ * This factory function wraps a regular Mastra Agent with Inngest's durable
274
+ * execution capabilities. The returned InngestAgent can be registered with
275
+ * Mastra, and the required workflow will be automatically registered.
276
+ *
277
+ * @param options - Configuration options
278
+ * @returns An InngestAgent that can be registered with Mastra
279
+ *
280
+ * @example
281
+ * ```typescript
282
+ * const agent = new Agent({
283
+ * id: 'my-agent',
284
+ * instructions: 'You are helpful',
285
+ * model: openai('gpt-4'),
286
+ * });
287
+ *
288
+ * const durableAgent = createInngestAgent({ agent, inngest });
289
+ *
290
+ * const mastra = new Mastra({
291
+ * agents: { myAgent: durableAgent },
292
+ * });
293
+ * ```
294
+ */
295
+ export declare function createInngestAgent<TOutput = undefined>(options: CreateInngestAgentOptions): InngestAgent<TOutput>;
296
+ /**
297
+ * Check if an object is an InngestAgent
298
+ */
299
+ export declare function isInngestAgent(obj: any): obj is InngestAgent;
300
+ //# sourceMappingURL=create-inngest-agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-inngest-agent.d.ts","sourceRoot":"","sources":["../../src/durable-agent/create-inngest-agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEvE,OAAO,KAAK,EACV,oBAAoB,EACpB,wBAAwB,EACxB,uBAAuB,EACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AASvC;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,sDAAsD;IACtD,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC5B,8BAA8B;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,kDAAkD;IAClD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,kGAAkG;IAClG,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB,CAAC,MAAM,GAAG,SAAS;IAC3D,yEAAyE;IACzE,YAAY,CAAC,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;IAC7D,kCAAkC;IAClC,OAAO,CAAC,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC;IACnD,2BAA2B;IAC3B,MAAM,CAAC,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC;IACjD,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,cAAc,CAAC,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,CAAC;IACjE,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;IACrD,wBAAwB;IACxB,WAAW,CAAC,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC;IAC3D,8BAA8B;IAC9B,UAAU,CAAC,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IACzD,qBAAqB;IACrB,aAAa,CAAC,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC;IAC/D,0CAA0C;IAC1C,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,2CAA2C;IAC3C,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,oCAAoC;IACpC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,mCAAmC;IACnC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gCAAgC;IAChC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,sCAAsC;IACtC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,kCAAkC;IAClC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,wBAAwB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,uCAAuC;IACvC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,wBAAwB;IACxB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,sCAAsC;IACtC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,uBAAuB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB,CAAC,MAAM,GAAG,SAAS;IAC1D,2BAA2B;IAC3B,MAAM,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAClC,gFAAgF;IAChF,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;IACzC,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uBAAuB;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,YAAY,CAAC,OAAO,GAAG,SAAS;IAC/C,eAAe;IACf,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,iBAAiB;IACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IACzC,yBAAyB;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAEnC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,MAAM,CACJ,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,CAAC,EAAE,yBAAyB,CAAC,OAAO,CAAC,GAC3C,OAAO,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC;IAE9C;;OAEG;IACH,MAAM,CACJ,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,OAAO,EACnB,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9D,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,wBAAwB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1E,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAClE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACjD,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,uBAAuB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KACvE,GACA,OAAO,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC;IAE9C;;OAEG;IACH,OAAO,CACL,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,CAAC,EAAE,qBAAqB,CAAC,OAAO,CAAC,GACvC,OAAO,CAAC;QACT,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,GAAG,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;IAEH;;;;;;OAMG;IACH,OAAO,CACL,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9D,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,wBAAwB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1E,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAClE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACjD,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,uBAAuB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KACvE,GACA,OAAO,CAAC,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAEnG;;;;OAIG;IACH,mBAAmB,IAAI,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;IAErE;;;;OAIG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAOlC,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,qBAAqB,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACzF,sEAAsE;IACtE,cAAc,IAAI,MAAM,CAAC;IACzB,uEAAuE;IACvE,eAAe,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IACrC,4EAA4E;IAC5E,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAC/B,4EAA4E;IAC5E,MAAM,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAC5B,gEAAgE;IAChE,QAAQ,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAC9B,0EAA0E;IAC1E,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAC/B,4EAA4E;IAC5E,YAAY,IAAI,OAAO,CAAC;IACxB,oEAAoE;IACpE,YAAY,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAClC,0DAA0D;IAC1D,UAAU,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAChC,yDAAyD;IACzD,aAAa,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IACnC,wEAAwE;IACxE,iBAAiB,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IACvC,sEAAsE;IACtE,+BAA+B,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IACrD,oEAAoE;IACpE,6BAA6B,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IACnD,+DAA+D;IAC/D,YAAY,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAClC,6EAA6E;IAC7E,+BAA+B,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IACrD,sEAAsE;IACtE,WAAW,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IACjC,uEAAuE;IACvE,YAAY,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAClC,sEAAsE;IACtE,cAAc,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IACpC,sEAAsE;IACtE,eAAe,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IACrC,6EAA6E;IAC7E,aAAa,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IACnC,4EAA4E;IAC5E,sBAAsB,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAC5C,+DAA+D;IAC/D,WAAW,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IACjC,wEAAwE;IACxE,oBAAoB,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;IAC1C,6EAA6E;IAC7E,gBAAgB,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;CACvC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAG,SAAS,EAAE,OAAO,EAAE,yBAAyB,GAAG,YAAY,CAAC,OAAO,CAAC,CAgZjH;AAMD;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,YAAY,CAU5D"}
@@ -0,0 +1,55 @@
1
+ import type { Inngest } from 'inngest';
2
+ /**
3
+ * Options for creating an Inngest durable agentic workflow
4
+ */
5
+ export interface InngestDurableAgenticWorkflowOptions {
6
+ /** Inngest client instance */
7
+ inngest: Inngest;
8
+ /** Maximum number of agentic loop iterations */
9
+ maxSteps?: number;
10
+ }
11
+ /** Inngest-prefixed workflow IDs */
12
+ export declare const InngestDurableStepIds: {
13
+ readonly AGENTIC_EXECUTION: "inngest:durable-agentic-execution";
14
+ readonly AGENTIC_LOOP: "inngest:durable-agentic-loop";
15
+ };
16
+ export declare function createInngestDurableAgenticWorkflow(options: InngestDurableAgenticWorkflowOptions): import("@mastra/core/workflows").Workflow<import("../types").InngestEngineType, never[], "inngest:durable-agentic-loop", any, {
17
+ runId: string;
18
+ agentId: string;
19
+ messageListState: any;
20
+ toolsMetadata: any[];
21
+ modelConfig: {
22
+ provider: string;
23
+ modelId: string;
24
+ specificationVersion?: string | undefined;
25
+ settings?: Record<string, any> | undefined;
26
+ };
27
+ options: any;
28
+ state: any;
29
+ messageId: string;
30
+ agentName?: string | undefined;
31
+ agentSpanData?: any;
32
+ modelSpanData?: any;
33
+ stepIndex?: number | undefined;
34
+ }, {
35
+ messageListState: any;
36
+ messageId: string;
37
+ stepResult: any;
38
+ output: {
39
+ usage: any;
40
+ steps: any[];
41
+ text?: string | undefined;
42
+ };
43
+ state: any;
44
+ }, {
45
+ messageListState: any;
46
+ messageId: string;
47
+ stepResult: any;
48
+ output: {
49
+ usage: any;
50
+ steps: any[];
51
+ text?: string | undefined;
52
+ };
53
+ state: any;
54
+ }, unknown>;
55
+ //# sourceMappingURL=create-inngest-agentic-workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-inngest-agentic-workflow.d.ts","sourceRoot":"","sources":["../../src/durable-agent/create-inngest-agentic-workflow.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AA2BvC;;GAEG;AACH,MAAM,WAAW,oCAAoC;IACnD,8BAA8B;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAuCD,oCAAoC;AACpC,eAAO,MAAM,qBAAqB;;;CAGxB,CAAC;AAEX,wBAAgB,mCAAmC,CAAC,OAAO,EAAE,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAgUhG"}