@axiom-lattice/gateway 1.0.11 → 1.0.13
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/.turbo/turbo-build.log +10 -10
- package/RESUME_STREAM_CONTENT_BASED.md +325 -0
- package/RESUME_STREAM_README.md +388 -0
- package/dist/index.d.mts +47 -1
- package/dist/index.d.ts +47 -1
- package/dist/index.js +324 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +331 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -3
- package/src/controllers/run.ts +62 -1
- package/src/index.ts +4 -4
- package/src/routes/index.ts +36 -3
- package/src/schemas/index.ts +194 -0
- package/src/services/agent_service.ts +129 -15
- package/src/swagger.ts +77 -0
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
# Resume Stream Feature
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The `resume_stream` feature allows you to continue receiving streaming chunks from a known position. This is particularly useful for scenarios where the client connection is interrupted (e.g., page refresh, network issues) and you want to seamlessly continue from where you left off.
|
|
6
|
+
|
|
7
|
+
## Architecture
|
|
8
|
+
|
|
9
|
+
### ChunkBuffer Integration
|
|
10
|
+
|
|
11
|
+
The feature leverages the `ChunkBuffer` module from `@axiom-lattice/core` to:
|
|
12
|
+
|
|
13
|
+
- Store streaming chunks in memory
|
|
14
|
+
- Track thread status (active/completed/aborted)
|
|
15
|
+
- Provide TTL-based automatic cleanup
|
|
16
|
+
- Calculate and return only new chunks since a known position
|
|
17
|
+
|
|
18
|
+
### How It Works
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
┌─────────────────┐
|
|
22
|
+
│ Original │
|
|
23
|
+
│ Streaming │ ──► Chunks stored in ChunkBuffer
|
|
24
|
+
│ (agent_stream) │ (thread_id, message_id, content)
|
|
25
|
+
└─────────────────┘
|
|
26
|
+
│
|
|
27
|
+
│ Connection lost / Page refresh
|
|
28
|
+
│
|
|
29
|
+
▼
|
|
30
|
+
┌─────────────────┐
|
|
31
|
+
│ Resume Stream │
|
|
32
|
+
│ (from known │ ──► Polls for new chunks
|
|
33
|
+
│ position) │ Returns only new content
|
|
34
|
+
└─────────────────┘ Ends when thread completes
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## API Reference
|
|
38
|
+
|
|
39
|
+
### `resume_stream(options)`
|
|
40
|
+
|
|
41
|
+
Creates an async iterator that yields new chunks as they arrive.
|
|
42
|
+
|
|
43
|
+
#### Parameters
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
{
|
|
47
|
+
thread_id: string; // Thread identifier
|
|
48
|
+
message_id: string; // Message identifier (usually run_id)
|
|
49
|
+
known_content: string; // Content already received (used to find resume position)
|
|
50
|
+
poll_interval?: number; // Polling interval in ms (default: 100)
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
#### Returns
|
|
55
|
+
|
|
56
|
+
An async iterable object with `Symbol.asyncIterator`:
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
{
|
|
60
|
+
content: string; // Chunk content
|
|
61
|
+
timestamp: number; // When chunk was added
|
|
62
|
+
messageId: string; // Message identifier
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
#### Behavior
|
|
67
|
+
|
|
68
|
+
- **Polling**: Checks for new chunks every `poll_interval` milliseconds
|
|
69
|
+
- **Status Check**: Monitors thread status (active/completed/aborted)
|
|
70
|
+
- **Timeout**: Automatically stops after 30 seconds of no new data
|
|
71
|
+
- **Completion**: Exits when thread is no longer active
|
|
72
|
+
|
|
73
|
+
## Usage Examples
|
|
74
|
+
|
|
75
|
+
### Example 1: Basic Resume After Page Refresh
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import {
|
|
79
|
+
resume_stream,
|
|
80
|
+
get_accumulated_content,
|
|
81
|
+
} from "./services/agent_service";
|
|
82
|
+
|
|
83
|
+
// Client already received content before refresh (e.g., from localStorage or state)
|
|
84
|
+
const knownContent = "Hello world! This is content I already received...";
|
|
85
|
+
|
|
86
|
+
const stream = await resume_stream({
|
|
87
|
+
thread_id: "thread-123",
|
|
88
|
+
message_id: "msg-abc-456",
|
|
89
|
+
known_content: knownContent,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Consume new chunks
|
|
93
|
+
for await (const chunk of stream) {
|
|
94
|
+
console.log("New content:", chunk.content);
|
|
95
|
+
displayInUI(chunk.content); // Update your UI
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
console.log("Stream completed!");
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Example 2: Check Status Before Resuming
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { get_thread_status, resume_stream } from "./services/agent_service";
|
|
105
|
+
|
|
106
|
+
// Check thread status first
|
|
107
|
+
const status = await get_thread_status("thread-123");
|
|
108
|
+
|
|
109
|
+
if (!status.exists) {
|
|
110
|
+
console.log("Thread not found or expired");
|
|
111
|
+
} else if (status.status === "completed") {
|
|
112
|
+
// Thread already finished, get full content
|
|
113
|
+
const content = await get_accumulated_content("thread-123");
|
|
114
|
+
displayFullContent(content);
|
|
115
|
+
} else if (status.status === "active") {
|
|
116
|
+
// Thread still streaming, resume from current position
|
|
117
|
+
const currentContent = await get_accumulated_content("thread-123");
|
|
118
|
+
|
|
119
|
+
const stream = await resume_stream({
|
|
120
|
+
thread_id: "thread-123",
|
|
121
|
+
message_id: "msg-123",
|
|
122
|
+
known_content: currentContent,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
for await (const chunk of stream) {
|
|
126
|
+
appendToUI(chunk.content);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Example 3: Express/Fastify Endpoint (SSE)
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
import express from "express";
|
|
135
|
+
import { resume_stream } from "./services/agent_service";
|
|
136
|
+
|
|
137
|
+
const app = express();
|
|
138
|
+
|
|
139
|
+
app.post("/api/resume-stream", async (req, res) => {
|
|
140
|
+
const { thread_id, message_id, known_content } = req.body;
|
|
141
|
+
|
|
142
|
+
// Set up Server-Sent Events
|
|
143
|
+
res.setHeader("Content-Type", "text/event-stream");
|
|
144
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
145
|
+
res.setHeader("Connection", "keep-alive");
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
const stream = await resume_stream({
|
|
149
|
+
thread_id,
|
|
150
|
+
message_id,
|
|
151
|
+
known_content,
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
for await (const chunk of stream) {
|
|
155
|
+
res.write(`data: ${JSON.stringify(chunk)}\n\n`);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
res.write("event: complete\ndata: {}\n\n");
|
|
159
|
+
res.end();
|
|
160
|
+
} catch (error) {
|
|
161
|
+
res.write(
|
|
162
|
+
`event: error\ndata: ${JSON.stringify({ error: error.message })}\n\n`
|
|
163
|
+
);
|
|
164
|
+
res.end();
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Example 4: React Hook
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
import { useState, useEffect } from 'react';
|
|
173
|
+
|
|
174
|
+
function useResumeStream(threadId: string, messageId: string, knownContent: string) {
|
|
175
|
+
const [content, setContent] = useState('');
|
|
176
|
+
const [isStreaming, setIsStreaming] = useState(false);
|
|
177
|
+
const [error, setError] = useState<Error | null>(null);
|
|
178
|
+
|
|
179
|
+
useEffect(() => {
|
|
180
|
+
let isCancelled = false;
|
|
181
|
+
|
|
182
|
+
async function startStream() {
|
|
183
|
+
setIsStreaming(true);
|
|
184
|
+
|
|
185
|
+
try {
|
|
186
|
+
const stream = await resume_stream({
|
|
187
|
+
thread_id: threadId,
|
|
188
|
+
message_id: messageId,
|
|
189
|
+
known_content: knownContent,
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
for await (const chunk of stream) {
|
|
193
|
+
if (isCancelled) break;
|
|
194
|
+
setContent(prev => prev + chunk.content);
|
|
195
|
+
}
|
|
196
|
+
} catch (err) {
|
|
197
|
+
if (!isCancelled) {
|
|
198
|
+
setError(err as Error);
|
|
199
|
+
}
|
|
200
|
+
} finally {
|
|
201
|
+
if (!isCancelled) {
|
|
202
|
+
setIsStreaming(false);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
startStream();
|
|
208
|
+
|
|
209
|
+
return () => {
|
|
210
|
+
isCancelled = true;
|
|
211
|
+
};
|
|
212
|
+
}, [threadId, messageId, knownContent]);
|
|
213
|
+
|
|
214
|
+
return { content, isStreaming, error };
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Usage in component
|
|
218
|
+
function ChatMessage({ threadId, messageId, initialContent }) {
|
|
219
|
+
const { content, isStreaming } = useResumeStream(
|
|
220
|
+
threadId,
|
|
221
|
+
messageId,
|
|
222
|
+
initialContent
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
return (
|
|
226
|
+
<div>
|
|
227
|
+
{initialContent + content}
|
|
228
|
+
{isStreaming && <span className="cursor">▋</span>}
|
|
229
|
+
</div>
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Related Functions
|
|
235
|
+
|
|
236
|
+
### `get_accumulated_content(thread_id)`
|
|
237
|
+
|
|
238
|
+
Get all accumulated content for a thread.
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
const content = await get_accumulated_content("thread-123");
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### `get_thread_status(thread_id)`
|
|
245
|
+
|
|
246
|
+
Get thread status and metadata.
|
|
247
|
+
|
|
248
|
+
```typescript
|
|
249
|
+
const status = await get_thread_status("thread-123");
|
|
250
|
+
// {
|
|
251
|
+
// exists: true,
|
|
252
|
+
// status: 'active' | 'completed' | 'aborted',
|
|
253
|
+
// chunkCount: 42,
|
|
254
|
+
// createdAt: 1234567890,
|
|
255
|
+
// updatedAt: 1234567900
|
|
256
|
+
// }
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### `get_active_threads()`
|
|
260
|
+
|
|
261
|
+
Get all currently active threads.
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
const activeThreads = await get_active_threads();
|
|
265
|
+
// ['thread-1', 'thread-2', 'thread-3']
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### `clear_thread_buffer(thread_id)`
|
|
269
|
+
|
|
270
|
+
Manually clear a thread's buffer.
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
await clear_thread_buffer("thread-123");
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Configuration
|
|
277
|
+
|
|
278
|
+
### TTL (Time-To-Live)
|
|
279
|
+
|
|
280
|
+
Threads are automatically cleaned up after 1 hour of inactivity:
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
// In agent_service.ts
|
|
284
|
+
const buffer = new InMemoryChunkBuffer({
|
|
285
|
+
ttl: 60 * 60 * 1000, // 1 hour
|
|
286
|
+
cleanupInterval: 5 * 60 * 1000, // Clean every 5 minutes
|
|
287
|
+
});
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Polling Interval
|
|
291
|
+
|
|
292
|
+
Adjust polling frequency based on your needs:
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
// Fast polling for real-time updates
|
|
296
|
+
const stream = await resume_stream({
|
|
297
|
+
thread_id: "thread-123",
|
|
298
|
+
message_id: "msg-123",
|
|
299
|
+
known_content: knownContent,
|
|
300
|
+
poll_interval: 50, // Check every 50ms
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
// Slower polling to reduce server load
|
|
304
|
+
const stream = await resume_stream({
|
|
305
|
+
thread_id: "thread-123",
|
|
306
|
+
message_id: "msg-123",
|
|
307
|
+
known_content: knownContent,
|
|
308
|
+
poll_interval: 500, // Check every 500ms
|
|
309
|
+
});
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Timeout
|
|
313
|
+
|
|
314
|
+
The resume stream automatically times out after 30 seconds of no new data:
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
// In agent_service.ts - resume_stream function
|
|
318
|
+
const maxIdleTime = 30000; // 30 seconds
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Error Handling
|
|
322
|
+
|
|
323
|
+
### Thread Not Found
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
const stream = await resume_stream({
|
|
327
|
+
thread_id: "non-existent",
|
|
328
|
+
message_id: "msg-123",
|
|
329
|
+
known_content: "",
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
// Stream will exit immediately if thread doesn't exist
|
|
333
|
+
for await (const chunk of stream) {
|
|
334
|
+
// Won't execute
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Network Errors
|
|
339
|
+
|
|
340
|
+
```typescript
|
|
341
|
+
try {
|
|
342
|
+
const stream = await resume_stream({
|
|
343
|
+
thread_id: "thread-123",
|
|
344
|
+
message_id: "msg-123",
|
|
345
|
+
known_content: previousContent,
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
for await (const chunk of stream) {
|
|
349
|
+
displayChunk(chunk);
|
|
350
|
+
}
|
|
351
|
+
} catch (error) {
|
|
352
|
+
console.error("Stream error:", error);
|
|
353
|
+
showErrorToUser("Failed to resume stream");
|
|
354
|
+
}
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## Best Practices
|
|
358
|
+
|
|
359
|
+
1. **Always Check Status First**: Check thread status before attempting to resume
|
|
360
|
+
2. **Store Message ID**: Keep track of the `message_id` (usually `run_id`) with your content
|
|
361
|
+
3. **Preserve Content Exactly**: Store the exact content as received (no formatting/processing)
|
|
362
|
+
4. **Handle Completion**: Be prepared for the stream to end at any time
|
|
363
|
+
5. **Implement Retry Logic**: Add retry mechanism for transient failures
|
|
364
|
+
6. **Set Appropriate Poll Interval**: Balance between responsiveness and server load
|
|
365
|
+
7. **Content Matching**: The algorithm matches content intelligently - exact match, prefix, or suffix
|
|
366
|
+
|
|
367
|
+
## Performance Considerations
|
|
368
|
+
|
|
369
|
+
- **Memory Usage**: Chunks are stored in memory (consider TTL for long-running applications)
|
|
370
|
+
- **Polling Overhead**: Lower `poll_interval` increases server load but improves responsiveness
|
|
371
|
+
- **Concurrent Streams**: Multiple resume streams can run concurrently
|
|
372
|
+
- **Cleanup**: Old threads are automatically cleaned up based on TTL
|
|
373
|
+
|
|
374
|
+
## Limitations
|
|
375
|
+
|
|
376
|
+
- **In-Memory Only**: Current implementation stores chunks in memory (lost on server restart)
|
|
377
|
+
- **Single Message Per Thread**: Designed for one active message per thread
|
|
378
|
+
- **Content Matching**: Relies on exact content matching (whitespace, encoding must match)
|
|
379
|
+
- **No Persistence**: Chunks are not persisted to disk or database
|
|
380
|
+
- **Performance**: Content matching is O(n) where n is number of chunks
|
|
381
|
+
|
|
382
|
+
## Future Enhancements
|
|
383
|
+
|
|
384
|
+
- **Persistent Storage**: Add Redis or database backend for persistence across restarts
|
|
385
|
+
- **WebSocket Support**: Direct WebSocket integration for lower latency
|
|
386
|
+
- **Event-Based Notifications**: Use event emitters instead of polling
|
|
387
|
+
- **Compression**: Compress stored chunks to reduce memory usage
|
|
388
|
+
- **Multi-Message Support**: Handle multiple concurrent messages per thread
|
package/dist/index.d.mts
CHANGED
|
@@ -1,10 +1,56 @@
|
|
|
1
|
-
import * as fastify from 'fastify';
|
|
2
1
|
import * as http from 'http';
|
|
2
|
+
import * as fastify from 'fastify';
|
|
3
|
+
|
|
4
|
+
declare const defaultSwaggerConfig: {
|
|
5
|
+
openapi: {
|
|
6
|
+
openapi: string;
|
|
7
|
+
info: {
|
|
8
|
+
title: string;
|
|
9
|
+
description: string;
|
|
10
|
+
version: string;
|
|
11
|
+
contact: {
|
|
12
|
+
name: string;
|
|
13
|
+
email: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
servers: {
|
|
17
|
+
url: string;
|
|
18
|
+
description: string;
|
|
19
|
+
}[];
|
|
20
|
+
components: {
|
|
21
|
+
securitySchemes: {
|
|
22
|
+
bearerAuth: {
|
|
23
|
+
type: "http";
|
|
24
|
+
scheme: "bearer";
|
|
25
|
+
bearerFormat: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
security: {
|
|
30
|
+
bearerAuth: never[];
|
|
31
|
+
}[];
|
|
32
|
+
tags: {
|
|
33
|
+
name: string;
|
|
34
|
+
description: string;
|
|
35
|
+
}[];
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
declare const defaultSwaggerUiConfig: {
|
|
39
|
+
routePrefix: string;
|
|
40
|
+
uiConfig: {
|
|
41
|
+
docExpansion: "full";
|
|
42
|
+
deepLinking: boolean;
|
|
43
|
+
};
|
|
44
|
+
staticCSP: boolean;
|
|
45
|
+
transformStaticCSP: (header: string) => string;
|
|
46
|
+
};
|
|
3
47
|
|
|
4
48
|
declare const LatticeGateway: {
|
|
5
49
|
startAsHttpEndpoint: ({ port }: {
|
|
6
50
|
port: number;
|
|
7
51
|
}) => Promise<void>;
|
|
52
|
+
configureSwagger: (app: fastify.FastifyInstance, customSwaggerConfig?: Partial<typeof defaultSwaggerConfig>, customSwaggerUiConfig?: Partial<typeof defaultSwaggerUiConfig>) => Promise<void>;
|
|
53
|
+
registerLatticeRoutes: (app: fastify.FastifyInstance) => void;
|
|
8
54
|
app: fastify.FastifyInstance<http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>, http.IncomingMessage, http.ServerResponse<http.IncomingMessage>, fastify.FastifyBaseLogger, fastify.FastifyTypeProviderDefault> & PromiseLike<fastify.FastifyInstance<http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>, http.IncomingMessage, http.ServerResponse<http.IncomingMessage>, fastify.FastifyBaseLogger, fastify.FastifyTypeProviderDefault>> & {
|
|
9
55
|
__linterBrands: "SafePromiseLike";
|
|
10
56
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,56 @@
|
|
|
1
|
-
import * as fastify from 'fastify';
|
|
2
1
|
import * as http from 'http';
|
|
2
|
+
import * as fastify from 'fastify';
|
|
3
|
+
|
|
4
|
+
declare const defaultSwaggerConfig: {
|
|
5
|
+
openapi: {
|
|
6
|
+
openapi: string;
|
|
7
|
+
info: {
|
|
8
|
+
title: string;
|
|
9
|
+
description: string;
|
|
10
|
+
version: string;
|
|
11
|
+
contact: {
|
|
12
|
+
name: string;
|
|
13
|
+
email: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
servers: {
|
|
17
|
+
url: string;
|
|
18
|
+
description: string;
|
|
19
|
+
}[];
|
|
20
|
+
components: {
|
|
21
|
+
securitySchemes: {
|
|
22
|
+
bearerAuth: {
|
|
23
|
+
type: "http";
|
|
24
|
+
scheme: "bearer";
|
|
25
|
+
bearerFormat: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
security: {
|
|
30
|
+
bearerAuth: never[];
|
|
31
|
+
}[];
|
|
32
|
+
tags: {
|
|
33
|
+
name: string;
|
|
34
|
+
description: string;
|
|
35
|
+
}[];
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
declare const defaultSwaggerUiConfig: {
|
|
39
|
+
routePrefix: string;
|
|
40
|
+
uiConfig: {
|
|
41
|
+
docExpansion: "full";
|
|
42
|
+
deepLinking: boolean;
|
|
43
|
+
};
|
|
44
|
+
staticCSP: boolean;
|
|
45
|
+
transformStaticCSP: (header: string) => string;
|
|
46
|
+
};
|
|
3
47
|
|
|
4
48
|
declare const LatticeGateway: {
|
|
5
49
|
startAsHttpEndpoint: ({ port }: {
|
|
6
50
|
port: number;
|
|
7
51
|
}) => Promise<void>;
|
|
52
|
+
configureSwagger: (app: fastify.FastifyInstance, customSwaggerConfig?: Partial<typeof defaultSwaggerConfig>, customSwaggerUiConfig?: Partial<typeof defaultSwaggerUiConfig>) => Promise<void>;
|
|
53
|
+
registerLatticeRoutes: (app: fastify.FastifyInstance) => void;
|
|
8
54
|
app: fastify.FastifyInstance<http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>, http.IncomingMessage, http.ServerResponse<http.IncomingMessage>, fastify.FastifyBaseLogger, fastify.FastifyTypeProviderDefault> & PromiseLike<fastify.FastifyInstance<http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>, http.IncomingMessage, http.ServerResponse<http.IncomingMessage>, fastify.FastifyBaseLogger, fastify.FastifyTypeProviderDefault>> & {
|
|
9
55
|
__linterBrands: "SafePromiseLike";
|
|
10
56
|
};
|