convex-durable-agents 0.1.0 → 0.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.
- package/README.md +200 -37
- package/dist/client/index.d.ts +124 -66
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +119 -16
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/component.d.ts +8 -0
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/agent.d.ts.map +1 -1
- package/dist/component/agent.js +42 -10
- package/dist/component/agent.js.map +1 -1
- package/dist/component/messages.d.ts +7 -7
- package/dist/component/messages.d.ts.map +1 -1
- package/dist/component/messages.js +2 -2
- package/dist/component/messages.js.map +1 -1
- package/dist/component/schema.d.ts +22 -18
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +3 -0
- package/dist/component/schema.js.map +1 -1
- package/dist/component/streams.d.ts.map +1 -1
- package/dist/component/streams.js +4 -1
- package/dist/component/streams.js.map +1 -1
- package/dist/component/threads.d.ts +22 -8
- package/dist/component/threads.d.ts.map +1 -1
- package/dist/component/threads.js +20 -4
- package/dist/component/threads.js.map +1 -1
- package/dist/component/tool_calls.d.ts +7 -6
- package/dist/component/tool_calls.d.ts.map +1 -1
- package/dist/component/tool_calls.js +2 -2
- package/dist/component/tool_calls.js.map +1 -1
- package/dist/react/index.d.ts +2 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +30 -17
- package/dist/react/index.js.map +1 -1
- package/package.json +5 -2
- package/src/client/index.ts +261 -20
- package/src/client/setup.test.ts +2 -8
- package/src/component/_generated/component.ts +11 -1
- package/src/component/agent.ts +60 -11
- package/src/component/component.test.ts +25 -7
- package/src/component/messages.ts +7 -7
- package/src/component/schema.ts +3 -0
- package/src/component/streams.ts +4 -1
- package/src/component/threads.ts +25 -7
- package/src/component/tool_calls.ts +7 -7
- package/src/react/index.ts +46 -39
- package/src/test.ts +1 -4
package/README.md
CHANGED
|
@@ -2,20 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://badge.fury.io/js/convex-durable-agents)
|
|
4
4
|
|
|
5
|
-
A Convex component for building durable AI agents with an async tool loop. The goal of this component is to provide a
|
|
5
|
+
A Convex component for building durable AI agents with an async tool loop. The goal of this component is to provide a
|
|
6
|
+
way to build AI agents that can run indefinitely and survive failures and restarts. It provides some of the
|
|
7
|
+
functionality of the [Convex Agents Component](https://www.convex.dev/components/agent) (such as persistent streaming),
|
|
8
|
+
while deliberately leaving out some of the more advanced features (context management, RAG, rate limiting, etc.). The
|
|
9
|
+
component is built on top of the [AI SDK v6](https://ai-sdk.dev/) SDK and aims to expose its full `streamText` API with
|
|
10
|
+
persistence and durable execution.
|
|
6
11
|
|
|
7
|
-
**Note:** This component is still in early development and is not yet ready for production use. The API will very likely
|
|
12
|
+
**Note:** This component is still in early development and is not yet ready for production use. The API will very likely
|
|
13
|
+
change before a first stable release.
|
|
8
14
|
|
|
9
15
|
## Features
|
|
10
16
|
|
|
11
17
|
- **Async Execution**: Agent tool loop is executed asynchronously to avoid time limits of convex actions
|
|
12
18
|
- **Tool Execution**: via convex actions - support for both sync and async tools
|
|
13
19
|
- **Automatic Retries**: Failed tool calls are automatically retried
|
|
20
|
+
- **Workpool Support**: Optionally route agent and tool execution through `@convex-dev/workpool` for parallelism control
|
|
21
|
+
and retry mechanisms
|
|
14
22
|
|
|
15
23
|
## Roadmap
|
|
16
24
|
|
|
17
25
|
- **Durable Execution**: Agent tool loops survive crashes and dev server restarts
|
|
18
|
-
- **Workpool/Workflow Support**: Support for workpool and workflow execution
|
|
19
26
|
|
|
20
27
|
## Installation
|
|
21
28
|
|
|
@@ -50,16 +57,12 @@ Create a chat handler with your AI model and tools:
|
|
|
50
57
|
|
|
51
58
|
import { z } from "zod";
|
|
52
59
|
import { components, internal } from "./_generated/api";
|
|
53
|
-
import {
|
|
54
|
-
createActionTool,
|
|
55
|
-
defineAgentApi,
|
|
56
|
-
streamHandlerAction,
|
|
57
|
-
} from "convex-durable-agents";
|
|
60
|
+
import { createActionTool, defineAgentApi, streamHandlerAction } from "convex-durable-agents";
|
|
58
61
|
import { openai } from "@ai-sdk/openai";
|
|
59
62
|
|
|
60
63
|
// Define the stream handler with your model and tools
|
|
61
64
|
export const chatAgentHandler = streamHandlerAction(components.durableAgents, {
|
|
62
|
-
model:
|
|
65
|
+
model: "anthropic/claude-haiku-4.5",
|
|
63
66
|
system: "You are a helpful AI assistant.",
|
|
64
67
|
tools: {
|
|
65
68
|
get_weather: createActionTool({
|
|
@@ -71,7 +74,7 @@ export const chatAgentHandler = streamHandlerAction(components.durableAgents, {
|
|
|
71
74
|
saveStreamDeltas: true, // Enable real-time streaming
|
|
72
75
|
});
|
|
73
76
|
|
|
74
|
-
// Export the agent API
|
|
77
|
+
// Export the agent API (public - callable from clients)
|
|
75
78
|
export const {
|
|
76
79
|
createThread,
|
|
77
80
|
sendMessage,
|
|
@@ -84,7 +87,60 @@ export const {
|
|
|
84
87
|
stopThread,
|
|
85
88
|
addToolResult,
|
|
86
89
|
addToolError,
|
|
87
|
-
} = defineAgentApi(components.durableAgents, internal.chat.chatAgentHandler
|
|
90
|
+
} = defineAgentApi(components.durableAgents, internal.chat.chatAgentHandler, {
|
|
91
|
+
// Optional: Add authorization to protect thread access
|
|
92
|
+
authorizationCallback: async (ctx, threadId) => {
|
|
93
|
+
// Example: verify the user owns this thread
|
|
94
|
+
// const identity = await ctx.auth.getUserIdentity();
|
|
95
|
+
// if (!identity) throw new Error("Unauthorized");
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
#### Using Internal API
|
|
101
|
+
|
|
102
|
+
If you want to restrict the agent API to only be callable from other Convex functions (not directly from clients), use
|
|
103
|
+
`defineInternalAgentApi` instead:
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
// convex/chat.ts
|
|
107
|
+
import { defineInternalAgentApi } from "convex-durable-agents";
|
|
108
|
+
|
|
109
|
+
// Export internal agent API (only callable from other Convex functions)
|
|
110
|
+
export const {
|
|
111
|
+
createThread,
|
|
112
|
+
sendMessage,
|
|
113
|
+
getThread,
|
|
114
|
+
// ... other functions
|
|
115
|
+
} = defineInternalAgentApi(components.durableAgents, internal.chat.chatAgentHandler);
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
This is useful when you want to:
|
|
119
|
+
|
|
120
|
+
- Add authentication/authorization checks before calling agent functions
|
|
121
|
+
- Wrap agent functions with additional business logic
|
|
122
|
+
- Prevent direct client access to the agent API
|
|
123
|
+
- Run agents in the background
|
|
124
|
+
|
|
125
|
+
You can then create your own public functions that call the internal API:
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
// convex/myChat.ts
|
|
129
|
+
import { mutation, query } from "./_generated/server";
|
|
130
|
+
import { internal } from "./_generated/api";
|
|
131
|
+
import { v } from "convex/values";
|
|
132
|
+
|
|
133
|
+
// Public wrapper with auth check
|
|
134
|
+
export const sendMessage = mutation({
|
|
135
|
+
args: { threadId: v.string(), prompt: v.string() },
|
|
136
|
+
handler: async (ctx, args) => {
|
|
137
|
+
const identity = await ctx.auth.getUserIdentity();
|
|
138
|
+
if (!identity) throw new Error("Not authenticated");
|
|
139
|
+
|
|
140
|
+
// Call the internal agent API
|
|
141
|
+
return ctx.runMutation(internal.chat.sendMessage, args);
|
|
142
|
+
},
|
|
143
|
+
});
|
|
88
144
|
```
|
|
89
145
|
|
|
90
146
|
### 3. Create Tool Handlers
|
|
@@ -119,12 +175,12 @@ import { api } from "../convex/_generated/api";
|
|
|
119
175
|
|
|
120
176
|
function ChatView({ threadId }: { threadId: string }) {
|
|
121
177
|
const sendMessage = useMutation(api.chat.sendMessage);
|
|
122
|
-
|
|
178
|
+
|
|
123
179
|
const { messages, status, isRunning } = useThread(
|
|
124
180
|
api.chat.listMessagesWithStreams,
|
|
125
181
|
api.chat.getThread,
|
|
126
182
|
{ threadId },
|
|
127
|
-
{ stream: true }
|
|
183
|
+
{ stream: true },
|
|
128
184
|
);
|
|
129
185
|
|
|
130
186
|
return (
|
|
@@ -134,7 +190,7 @@ function ChatView({ threadId }: { threadId: string }) {
|
|
|
134
190
|
<strong>{msg.role}:</strong> {msg.text}
|
|
135
191
|
</div>
|
|
136
192
|
))}
|
|
137
|
-
|
|
193
|
+
|
|
138
194
|
<input
|
|
139
195
|
onKeyPress={(e) => {
|
|
140
196
|
if (e.key === "Enter" && !isRunning) {
|
|
@@ -152,9 +208,9 @@ function ChatView({ threadId }: { threadId: string }) {
|
|
|
152
208
|
|
|
153
209
|
### Client API
|
|
154
210
|
|
|
155
|
-
#### `defineAgentApi(component, streamHandler)`
|
|
211
|
+
#### `defineAgentApi(component, streamHandler, options?)`
|
|
156
212
|
|
|
157
|
-
Creates the full agent API with
|
|
213
|
+
Creates the full agent API with **public** functions that can be called directly from clients:
|
|
158
214
|
|
|
159
215
|
- `createThread({ prompt? })` - Create a new conversation thread
|
|
160
216
|
- `sendMessage({ threadId, prompt })` - Send a message to a thread
|
|
@@ -168,6 +224,47 @@ Creates the full agent API with the following functions:
|
|
|
168
224
|
- `addToolResult({ toolCallId, result })` - Add result for async tool
|
|
169
225
|
- `addToolError({ toolCallId, error })` - Add error for async tool
|
|
170
226
|
|
|
227
|
+
**Options:**
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
type AgentApiOptions = {
|
|
231
|
+
authorizationCallback?: (ctx: QueryCtx | MutationCtx | ActionCtx, threadId: string) => Promise<void> | void;
|
|
232
|
+
workpoolEnqueueAction?: FunctionReference<"mutation", "internal">;
|
|
233
|
+
toolExecutionWorkpoolEnqueueAction?: FunctionReference<"mutation", "internal">;
|
|
234
|
+
};
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
- `authorizationCallback` - Called before any operation that accesses an existing thread. Use it to verify the user has
|
|
238
|
+
permission to access the thread. Throw an error to deny access.
|
|
239
|
+
- `workpoolEnqueueAction` - Route agent and tool execution through a workpool for parallelism control
|
|
240
|
+
- `toolExecutionWorkpoolEnqueueAction` - Override workpool for tool execution only (falls back to
|
|
241
|
+
`workpoolEnqueueAction` if not set)
|
|
242
|
+
|
|
243
|
+
**Protected endpoints:** `sendMessage`, `resumeThread`, `stopThread`, `getThread`, `listMessages`,
|
|
244
|
+
`listMessagesWithStreams`, `deleteThread`
|
|
245
|
+
|
|
246
|
+
**Example with ownership check:**
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
defineAgentApi(components.durableAgents, internal.chat.chatAgentHandler, {
|
|
250
|
+
authorizationCallback: async (ctx, threadId) => {
|
|
251
|
+
const identity = await ctx.auth.getUserIdentity();
|
|
252
|
+
if (!identity) throw new Error("Unauthorized");
|
|
253
|
+
|
|
254
|
+
// Query your threads table to verify ownership
|
|
255
|
+
const thread = await ctx.runQuery(api.threads.getOwner, { threadId });
|
|
256
|
+
if (thread?.userId !== identity.subject) {
|
|
257
|
+
throw new Error("Access denied");
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
});
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
#### `defineInternalAgentApi(component, streamHandler, options?)`
|
|
264
|
+
|
|
265
|
+
Same as `defineAgentApi` but creates internal functions that can only be called from other Convex functions. Use this
|
|
266
|
+
when you want to add authentication, authorization, or other business logic before calling agent functions.
|
|
267
|
+
|
|
171
268
|
#### `streamHandlerAction(component, options)`
|
|
172
269
|
|
|
173
270
|
Creates the stream handler action:
|
|
@@ -215,20 +312,15 @@ All-in-one hook for thread status and messages:
|
|
|
215
312
|
|
|
216
313
|
```ts
|
|
217
314
|
const {
|
|
218
|
-
messages,
|
|
219
|
-
thread,
|
|
220
|
-
status,
|
|
221
|
-
isLoading,
|
|
222
|
-
isRunning,
|
|
223
|
-
isComplete,
|
|
224
|
-
isFailed,
|
|
225
|
-
isStopped,
|
|
226
|
-
} = useThread(
|
|
227
|
-
api.chat.listMessagesWithStreams,
|
|
228
|
-
api.chat.getThread,
|
|
229
|
-
{ threadId },
|
|
230
|
-
{ stream: true }
|
|
231
|
-
);
|
|
315
|
+
messages, // UIMessage[]
|
|
316
|
+
thread, // ThreadDoc | null
|
|
317
|
+
status, // ThreadStatus
|
|
318
|
+
isLoading, // boolean
|
|
319
|
+
isRunning, // boolean
|
|
320
|
+
isComplete, // boolean
|
|
321
|
+
isFailed, // boolean
|
|
322
|
+
isStopped, // boolean
|
|
323
|
+
} = useThread(api.chat.listMessagesWithStreams, api.chat.getThread, { threadId }, { stream: true });
|
|
232
324
|
```
|
|
233
325
|
|
|
234
326
|
#### `useSmoothText(text, options?)`
|
|
@@ -247,8 +339,9 @@ const [visibleText, { cursor, isStreaming }] = useSmoothText(text, {
|
|
|
247
339
|
Subscribe to thread status changes:
|
|
248
340
|
|
|
249
341
|
```ts
|
|
250
|
-
const { thread, status, isRunning, isComplete, isFailed, isStopped } =
|
|
251
|
-
|
|
342
|
+
const { thread, status, isRunning, isComplete, isFailed, isStopped } = useThreadStatus(api.chat.getThread, {
|
|
343
|
+
threadId,
|
|
344
|
+
});
|
|
252
345
|
```
|
|
253
346
|
|
|
254
347
|
#### `useMessages(query, threadQuery, args)`
|
|
@@ -256,11 +349,7 @@ const { thread, status, isRunning, isComplete, isFailed, isStopped } =
|
|
|
256
349
|
Fetch and transform messages:
|
|
257
350
|
|
|
258
351
|
```ts
|
|
259
|
-
const { messages, isLoading, thread } = useMessages(
|
|
260
|
-
api.chat.listMessages,
|
|
261
|
-
api.chat.getThread,
|
|
262
|
-
{ threadId }
|
|
263
|
-
);
|
|
352
|
+
const { messages, isLoading, thread } = useMessages(api.chat.listMessages, api.chat.getThread, { threadId });
|
|
264
353
|
```
|
|
265
354
|
|
|
266
355
|
## Thread Status
|
|
@@ -273,6 +362,80 @@ Threads can be in one of these states:
|
|
|
273
362
|
- `failed` - An error occurred
|
|
274
363
|
- `stopped` - User stopped the conversation
|
|
275
364
|
|
|
365
|
+
## Workpool Integration
|
|
366
|
+
|
|
367
|
+
For advanced use cases, you can route agent execution through the `@convex-dev/workpool` component. This provides:
|
|
368
|
+
|
|
369
|
+
- **Parallelism Control**: Limit concurrent AI model calls and tool executions
|
|
370
|
+
- **Retry Mechanisms**: Automatic retries with exponential backoff for failed actions
|
|
371
|
+
- **Rate Limiting Protection**: Prevent overwhelming external APIs
|
|
372
|
+
|
|
373
|
+
### Setup
|
|
374
|
+
|
|
375
|
+
1. Install and configure the workpool component:
|
|
376
|
+
|
|
377
|
+
```ts
|
|
378
|
+
// convex/convex.config.ts
|
|
379
|
+
import { defineApp } from "convex/server";
|
|
380
|
+
import durableAgents from "convex-durable-agents/convex.config.js";
|
|
381
|
+
import workpool from "@convex-dev/workpool/convex.config.js";
|
|
382
|
+
|
|
383
|
+
const app = defineApp();
|
|
384
|
+
app.use(durableAgents);
|
|
385
|
+
app.use(workpool, { name: "agentWorkpool" });
|
|
386
|
+
|
|
387
|
+
export default app;
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
2. Create the workpool bridge:
|
|
391
|
+
|
|
392
|
+
```ts
|
|
393
|
+
// convex/workpool.ts
|
|
394
|
+
import { Workpool } from "@convex-dev/workpool";
|
|
395
|
+
import { components } from "./_generated/api";
|
|
396
|
+
import { createWorkpoolBridge } from "convex-durable-agents";
|
|
397
|
+
|
|
398
|
+
const pool = new Workpool(components.agentWorkpool, {
|
|
399
|
+
maxParallelism: 5,
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
export const { enqueueWorkpoolAction } = createWorkpoolBridge(pool);
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
3. Pass the workpool to your agent API:
|
|
406
|
+
|
|
407
|
+
```ts
|
|
408
|
+
// convex/chat.ts
|
|
409
|
+
export const {
|
|
410
|
+
createThread,
|
|
411
|
+
sendMessage,
|
|
412
|
+
// ...
|
|
413
|
+
} = defineAgentApi(components.durableAgents, internal.chat.chatAgentHandler, {
|
|
414
|
+
workpoolEnqueueAction: internal.workpool.enqueueWorkpoolAction,
|
|
415
|
+
});
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Separate Workpools for Tools
|
|
419
|
+
|
|
420
|
+
You can use different workpools for the stream handler and tool execution:
|
|
421
|
+
|
|
422
|
+
```ts
|
|
423
|
+
// convex/workpool.ts
|
|
424
|
+
const agentPool = new Workpool(components.agentWorkpool, { maxParallelism: 3 });
|
|
425
|
+
const toolPool = new Workpool(components.toolWorkpool, { maxParallelism: 10 });
|
|
426
|
+
|
|
427
|
+
export const { enqueueWorkpoolAction: enqueueAgentAction } = createWorkpoolBridge(agentPool);
|
|
428
|
+
export const { enqueueWorkpoolAction: enqueueToolAction } = createWorkpoolBridge(toolPool);
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
```ts
|
|
432
|
+
// convex/chat.ts
|
|
433
|
+
defineAgentApi(components.durableAgents, internal.chat.chatAgentHandler, {
|
|
434
|
+
workpoolEnqueueAction: internal.workpool.enqueueAgentAction,
|
|
435
|
+
toolExecutionWorkpoolEnqueueAction: internal.workpool.enqueueToolAction,
|
|
436
|
+
});
|
|
437
|
+
```
|
|
438
|
+
|
|
276
439
|
## Architecture
|
|
277
440
|
|
|
278
441
|
```
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ModelMessage, streamText } from "ai";
|
|
2
|
-
import { type FunctionReference, type GenericActionCtx, type GenericDataModel, type GenericMutationCtx, type GenericQueryCtx } from "convex/server";
|
|
2
|
+
import { type FunctionReference, type FunctionVisibility, type GenericActionCtx, type GenericDataModel, type GenericMutationCtx, type GenericQueryCtx, type RegisteredAction, type RegisteredMutation, type RegisteredQuery } from "convex/server";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import type { ComponentApi } from "../component/_generated/component.js";
|
|
5
5
|
import type { Id } from "../component/_generated/dataModel.js";
|
|
@@ -22,6 +22,8 @@ export type ThreadDoc = {
|
|
|
22
22
|
_creationTime: number;
|
|
23
23
|
status: ThreadStatus;
|
|
24
24
|
stopSignal: boolean;
|
|
25
|
+
streamId?: string | null;
|
|
26
|
+
streamFnHandle: string;
|
|
25
27
|
};
|
|
26
28
|
export type MessageDoc = {
|
|
27
29
|
_id: string;
|
|
@@ -109,87 +111,143 @@ type StreamHandlerArgs = Omit<Parameters<typeof streamText>[0], "tools" | "messa
|
|
|
109
111
|
/** Optional: Save streaming deltas to the database for real-time client updates */
|
|
110
112
|
saveStreamDeltas?: boolean | StreamingOptions;
|
|
111
113
|
transformMessages?: (messages: ModelMessage[]) => ModelMessage[];
|
|
114
|
+
/** Optional: Function to enqueue actions via workpool (used for both stream handler and tools unless overridden) */
|
|
115
|
+
workpoolEnqueueAction?: FunctionReference<"mutation", "internal">;
|
|
116
|
+
/** Optional: Override workpool for tool execution only */
|
|
117
|
+
toolExecutionWorkpoolEnqueueAction?: FunctionReference<"mutation", "internal">;
|
|
112
118
|
};
|
|
113
|
-
export declare function streamHandlerAction(component: ComponentApi, { tools, saveStreamDeltas, transformMessages, ...streamTextArgs }: StreamHandlerArgs):
|
|
119
|
+
export declare function streamHandlerAction(component: ComponentApi, { tools, saveStreamDeltas, transformMessages, ...streamTextArgs }: StreamHandlerArgs): RegisteredAction<"internal", {
|
|
114
120
|
threadId: string;
|
|
115
121
|
streamId: string;
|
|
116
122
|
}, Promise<null>>;
|
|
117
|
-
export
|
|
123
|
+
export type StreamArgs = {
|
|
124
|
+
kind: "list";
|
|
125
|
+
startOrder?: number;
|
|
126
|
+
} | {
|
|
127
|
+
kind: "deltas";
|
|
128
|
+
cursors: Array<{
|
|
129
|
+
streamId: string;
|
|
130
|
+
cursor: number;
|
|
131
|
+
}>;
|
|
132
|
+
};
|
|
133
|
+
export type StreamMessage = {
|
|
134
|
+
streamId: string;
|
|
135
|
+
status: "streaming" | "finished" | "aborted";
|
|
136
|
+
format?: "UIMessageChunk" | "TextStreamPart";
|
|
137
|
+
order: number;
|
|
118
138
|
threadId: string;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
139
|
+
};
|
|
140
|
+
export type StreamDelta = {
|
|
141
|
+
streamId: string;
|
|
142
|
+
start: number;
|
|
143
|
+
end: number;
|
|
144
|
+
parts: Array<unknown>;
|
|
145
|
+
};
|
|
146
|
+
export type MessagesWithStreamsResult = {
|
|
147
|
+
messages: MessageDoc[];
|
|
148
|
+
streams?: {
|
|
149
|
+
kind: "list";
|
|
150
|
+
messages: StreamMessage[];
|
|
151
|
+
} | {
|
|
152
|
+
kind: "deltas";
|
|
153
|
+
deltas: StreamDelta[];
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
export type AgentApi<V extends FunctionVisibility = "public"> = {
|
|
157
|
+
createThread: RegisteredAction<V, {
|
|
158
|
+
prompt?: string;
|
|
159
|
+
}, string>;
|
|
160
|
+
sendMessage: RegisteredMutation<V, {
|
|
124
161
|
threadId: string;
|
|
125
162
|
prompt: string;
|
|
126
|
-
},
|
|
127
|
-
resumeThread:
|
|
128
|
-
prompt?: string | undefined;
|
|
163
|
+
}, null>;
|
|
164
|
+
resumeThread: RegisteredMutation<V, {
|
|
129
165
|
threadId: string;
|
|
130
|
-
|
|
131
|
-
|
|
166
|
+
prompt?: string;
|
|
167
|
+
}, null>;
|
|
168
|
+
stopThread: RegisteredMutation<V, {
|
|
132
169
|
threadId: string;
|
|
133
|
-
},
|
|
134
|
-
getThread:
|
|
170
|
+
}, null>;
|
|
171
|
+
getThread: RegisteredQuery<V, {
|
|
135
172
|
threadId: string;
|
|
136
|
-
},
|
|
137
|
-
|
|
138
|
-
_id: string;
|
|
139
|
-
status: "streaming" | "awaiting_tool_results" | "completed" | "failed" | "stopped";
|
|
140
|
-
stopSignal: boolean;
|
|
141
|
-
streamFnHandle: string;
|
|
142
|
-
streamId?: string | null;
|
|
143
|
-
} | null>>;
|
|
144
|
-
listMessages: import("convex/server").RegisteredQuery<"public", {
|
|
173
|
+
}, ThreadDoc | null>;
|
|
174
|
+
listMessages: RegisteredQuery<V, {
|
|
145
175
|
threadId: string;
|
|
146
|
-
},
|
|
147
|
-
listMessagesWithStreams:
|
|
148
|
-
streamArgs?: {
|
|
149
|
-
startOrder?: number | undefined;
|
|
150
|
-
kind: "list";
|
|
151
|
-
} | {
|
|
152
|
-
kind: "deltas";
|
|
153
|
-
cursors: {
|
|
154
|
-
streamId: string;
|
|
155
|
-
cursor: number;
|
|
156
|
-
}[];
|
|
157
|
-
} | undefined;
|
|
176
|
+
}, MessageDoc[]>;
|
|
177
|
+
listMessagesWithStreams: RegisteredQuery<V, {
|
|
158
178
|
threadId: string;
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
status: "streaming" | "finished" | "aborted";
|
|
166
|
-
format?: "UIMessageChunk" | "TextStreamPart";
|
|
167
|
-
order: number;
|
|
168
|
-
threadId: string;
|
|
169
|
-
}>;
|
|
170
|
-
} | {
|
|
171
|
-
kind: "deltas";
|
|
172
|
-
deltas: Array<{
|
|
173
|
-
streamId: string;
|
|
174
|
-
start: number;
|
|
175
|
-
end: number;
|
|
176
|
-
parts: Array<unknown>;
|
|
177
|
-
}>;
|
|
178
|
-
};
|
|
179
|
-
}>>;
|
|
180
|
-
listThreads: import("convex/server").RegisteredQuery<"public", {
|
|
181
|
-
limit?: number | undefined;
|
|
182
|
-
}, Promise<ThreadDoc[]>>;
|
|
183
|
-
deleteThread: import("convex/server").RegisteredMutation<"public", {
|
|
179
|
+
streamArgs?: StreamArgs;
|
|
180
|
+
}, MessagesWithStreamsResult>;
|
|
181
|
+
listThreads: RegisteredQuery<V, {
|
|
182
|
+
limit?: number;
|
|
183
|
+
}, ThreadDoc[]>;
|
|
184
|
+
deleteThread: RegisteredMutation<V, {
|
|
184
185
|
threadId: string;
|
|
185
|
-
},
|
|
186
|
-
addToolResult:
|
|
186
|
+
}, null>;
|
|
187
|
+
addToolResult: RegisteredMutation<V, {
|
|
187
188
|
toolCallId: string;
|
|
188
|
-
result:
|
|
189
|
-
},
|
|
190
|
-
addToolError:
|
|
189
|
+
result: unknown;
|
|
190
|
+
}, null>;
|
|
191
|
+
addToolError: RegisteredMutation<V, {
|
|
191
192
|
toolCallId: string;
|
|
192
193
|
error: string;
|
|
194
|
+
}, null>;
|
|
195
|
+
};
|
|
196
|
+
export type AgentApiOptions = {
|
|
197
|
+
/** Optional authorization callback for thread access control */
|
|
198
|
+
authorizationCallback?: (ctx: QueryCtx | MutationCtx | ActionCtx, threadId: string) => Promise<void> | void;
|
|
199
|
+
/** Optional: Function to enqueue actions via workpool (used for both stream handler and tools unless overridden) */
|
|
200
|
+
workpoolEnqueueAction?: FunctionReference<"mutation", "internal">;
|
|
201
|
+
/** Optional: Override workpool for tool execution only */
|
|
202
|
+
toolExecutionWorkpoolEnqueueAction?: FunctionReference<"mutation", "internal">;
|
|
203
|
+
};
|
|
204
|
+
/**
|
|
205
|
+
* Define a public agent API that can be called from clients.
|
|
206
|
+
*/
|
|
207
|
+
export declare function defineAgentApi(component: ComponentApi, ref: FunctionReference<"action", "internal" | "public", {
|
|
208
|
+
threadId: string;
|
|
209
|
+
}>, options?: AgentApiOptions): AgentApi<"public">;
|
|
210
|
+
/**
|
|
211
|
+
* Define an internal agent API that can only be called from other Convex functions.
|
|
212
|
+
*/
|
|
213
|
+
export declare function defineInternalAgentApi(component: ComponentApi, ref: FunctionReference<"action", "internal" | "public", {
|
|
214
|
+
threadId: string;
|
|
215
|
+
}>, options?: AgentApiOptions): AgentApi<"internal">;
|
|
216
|
+
/**
|
|
217
|
+
* Type for a Workpool instance that has an enqueueAction method.
|
|
218
|
+
* This is compatible with @convex-dev/workpool's Workpool class.
|
|
219
|
+
*/
|
|
220
|
+
type WorkpoolLike = {
|
|
221
|
+
enqueueAction: (ctx: GenericMutationCtx<GenericDataModel>, fn: FunctionReference<"action", FunctionVisibility, any, any>, fnArgs: any, options?: any) => Promise<any>;
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* Creates a workpool bridge mutation that can be used with defineAgentApi.
|
|
225
|
+
*
|
|
226
|
+
* This helper creates an internal mutation that forwards action execution to your workpool,
|
|
227
|
+
* allowing the agent to use workpool's parallelism controls and retry mechanisms.
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```typescript
|
|
231
|
+
* // convex/workpool.ts
|
|
232
|
+
* import { Workpool } from "@convex-dev/workpool";
|
|
233
|
+
* import { components } from "./_generated/api";
|
|
234
|
+
* import { createWorkpoolBridge } from "convex-durable-agents";
|
|
235
|
+
*
|
|
236
|
+
* const pool = new Workpool(components.workpool, { maxParallelism: 5 });
|
|
237
|
+
* export const { enqueueWorkpoolAction } = createWorkpoolBridge(pool);
|
|
238
|
+
*
|
|
239
|
+
* // convex/chat.ts
|
|
240
|
+
* export const { createThread, sendMessage, ... } = defineAgentApi(
|
|
241
|
+
* components.durable_agent,
|
|
242
|
+
* internal.chat.chatAgentHandler,
|
|
243
|
+
* { workpoolEnqueueAction: internal.workpool.enqueueWorkpoolAction }
|
|
244
|
+
* );
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
export declare function createWorkpoolBridge(workpool: WorkpoolLike): {
|
|
248
|
+
enqueueWorkpoolAction: RegisteredMutation<"internal", {
|
|
249
|
+
action: string;
|
|
250
|
+
args: any;
|
|
193
251
|
}, Promise<null>>;
|
|
194
252
|
};
|
|
195
253
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,YAAY,EAAE,UAAU,EAAmB,MAAM,IAAI,CAAC;AAChF,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,YAAY,EAAE,UAAU,EAAmB,MAAM,IAAI,CAAC;AAChF,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EAMpB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,sCAAsC,CAAC;AAM/D,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC,EAAE,UAAU,CAAC,CAAC;AAC3E,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,EAAE,UAAU,GAAG,aAAa,CAAC,CAAC;AACjG,MAAM,MAAM,SAAS,GAAG,IAAI,CAC1B,gBAAgB,CAAC,gBAAgB,CAAC,EAClC,UAAU,GAAG,aAAa,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,WAAW,CAC5E,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;IAChC,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,MAAM,EAAE,OAAO,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,uBAAuB,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEtG,MAAM,MAAM,SAAS,GAAG;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAqBF,MAAM,MAAM,UAAU,GAAG;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE;QACP,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;QAC/C,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;KAClC,CAAC;CACH,CAAC;AAGF,MAAM,MAAM,QAAQ,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,OAAO,IAAI;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,iBAAiB,CAAC,QAAQ,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC;IAC5D,UAAU,CAAC,EAAE,KAAK,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAGF,MAAM,MAAM,SAAS,CAAC,KAAK,GAAG,OAAO,IAAI;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,iBAAiB,CAAC,QAAQ,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC;IAC7D,UAAU,CAAC,EAAE,KAAK,CAAC;CACpB,CAAC;AAGF,MAAM,MAAM,WAAW,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,OAAO,IAAI,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;AAGxG,MAAM,MAAM,qBAAqB,CAAC,KAAK,GAAG,OAAO,IAAI;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,KAAK,CAAC;CACb,CAAC;AAMF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACvB,OAAO,EAAE,iBAAiB,CAAC,QAAQ,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC;CAC7D,GAAG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAW1B;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACvB,QAAQ,EAAE,iBAAiB,CAAC,QAAQ,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC;CAC9D,GAAG,SAAS,CAAC,KAAK,CAAC,CAWnB;AAMD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AAuCF;;;;GAIG;AACH,qBAAa,aAAa;;aASN,SAAS,EAAE,YAAY;aACvB,GAAG,EAAE,SAAS;IAC9B,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,QAAQ;IAflB,QAAQ,EAAE,EAAE,CAAC,oBAAoB,CAAC,GAAG,SAAS,CAAC;IAK/C,eAAe,EAAE,eAAe,CAAC;gBAGf,SAAS,EAAE,YAAY,EACvB,GAAG,EAAE,SAAS,EACtB,MAAM,EAAE;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAChD,WAAW,CAAC,EAAE,WAAW,CAAC;KAC3B,EACO,QAAQ,EAAE;QAChB,QAAQ,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC;QACxB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,SAAS,CAAC;KACzD;IAoBG,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;IAY9B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAS9C,aAAa,CAAC,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAgD5D,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAYvB,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAa1C;AAkDD,KAAK,iBAAiB,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC,GAAG;IACjG,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IACrD,mFAAmF;IACnF,gBAAgB,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAAC;IAC9C,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,CAAC;IACjE,oHAAoH;IACpH,qBAAqB,CAAC,EAAE,iBAAiB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAClE,0DAA0D;IAC1D,kCAAkC,CAAC,EAAE,iBAAiB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;CAChF,CAAC;AAEF,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,YAAY,EACvB,EAAE,KAAK,EAAE,gBAAgB,EAAE,iBAA0C,EAAE,GAAG,cAAc,EAAE,EAAE,iBAAiB;;;kBA4M9G;AAkBD,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC;AAE7E,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,GAAG,UAAU,GAAG,SAAS,CAAC;IAC7C,MAAM,CAAC,EAAE,gBAAgB,GAAG,gBAAgB,CAAC;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,aAAa,EAAE,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,MAAM,EAAE,WAAW,EAAE,CAAA;KAAE,CAAC;CACnG,CAAC;AAEF,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,kBAAkB,GAAG,QAAQ,IAAI;IAC9D,YAAY,EAAE,gBAAgB,CAAC,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,MAAM,CAAC,CAAC;IAC/D,WAAW,EAAE,kBAAkB,CAAC,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,IAAI,CAAC,CAAC;IAC/E,YAAY,EAAE,kBAAkB,CAAC,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,IAAI,CAAC,CAAC;IACjF,UAAU,EAAE,kBAAkB,CAAC,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,IAAI,CAAC,CAAC;IAC9D,SAAS,EAAE,eAAe,CAAC,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,SAAS,GAAG,IAAI,CAAC,CAAC;IACtE,YAAY,EAAE,eAAe,CAAC,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IACrE,uBAAuB,EAAE,eAAe,CAAC,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,UAAU,CAAA;KAAE,EAAE,yBAAyB,CAAC,CAAC;IACtH,WAAW,EAAE,eAAe,CAAC,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IACjE,YAAY,EAAE,kBAAkB,CAAC,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,IAAI,CAAC,CAAC;IAChE,aAAa,EAAE,kBAAkB,CAAC,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,EAAE,IAAI,CAAC,CAAC;IACpF,YAAY,EAAE,kBAAkB,CAAC,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,IAAI,CAAC,CAAC;CAClF,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,gEAAgE;IAChE,qBAAqB,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,GAAG,WAAW,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC5G,oHAAoH;IACpH,qBAAqB,CAAC,EAAE,iBAAiB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAClE,0DAA0D;IAC1D,kCAAkC,CAAC,EAAE,iBAAiB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;CAChF,CAAC;AAqSF;;GAEG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,YAAY,EACvB,GAAG,EAAE,iBAAiB,CAAC,QAAQ,EAAE,UAAU,GAAG,QAAQ,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,EAC7E,OAAO,CAAC,EAAE,eAAe,GACxB,QAAQ,CAAC,QAAQ,CAAC,CAEpB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,YAAY,EACvB,GAAG,EAAE,iBAAiB,CAAC,QAAQ,EAAE,UAAU,GAAG,QAAQ,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,EAC7E,OAAO,CAAC,EAAE,eAAe,GACxB,QAAQ,CAAC,UAAU,CAAC,CAStB;AAMD;;;GAGG;AAEH,KAAK,YAAY,GAAG;IAClB,aAAa,EAAE,CACb,GAAG,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,EACzC,EAAE,EAAE,iBAAiB,CAAC,QAAQ,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG,CAAC,EAC7D,MAAM,EAAE,GAAG,EACX,OAAO,CAAC,EAAE,GAAG,KACV,OAAO,CAAC,GAAG,CAAC,CAAC;CACnB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,YAAY;;;;;EAkB1D"}
|