@mikesaintsg/core 0.0.2 → 0.0.3
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 +186 -41
- package/dist/index.d.ts +233 -142
- package/dist/index.js +101 -110
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
- ✅ **Shared Types** — Contracts used across multiple packages
|
|
14
14
|
- ✅ **Result Pattern** — Functional error handling (`ok`, `err`, `map`, `chain`)
|
|
15
15
|
- ✅ **Bridge Functions** — Connect packages without circular dependencies
|
|
16
|
-
- ✅ **
|
|
16
|
+
- ✅ **Adapter Interfaces** — Embedding, tool format, persistence, and policy adapters
|
|
17
|
+
- ✅ **Base Error Class** — `EcosystemError` for all package-specific errors
|
|
18
|
+
- ✅ **Content Hashing** — SHA-256 based deduplication support
|
|
17
19
|
- ✅ **Zero dependencies** — Built on native platform APIs
|
|
18
20
|
- ✅ **TypeScript first** — Full type safety with generics
|
|
19
21
|
- ✅ **Tree-shakeable** — ESM-only, import what you need
|
|
@@ -30,6 +32,8 @@ npm install @mikesaintsg/core
|
|
|
30
32
|
|
|
31
33
|
## Quick Start
|
|
32
34
|
|
|
35
|
+
### Result Pattern
|
|
36
|
+
|
|
33
37
|
```ts
|
|
34
38
|
import { ok, err, isOk, map, chain } from '@mikesaintsg/core'
|
|
35
39
|
import type { Result } from '@mikesaintsg/core'
|
|
@@ -55,6 +59,33 @@ function parse(s: string): Result<number, string> {
|
|
|
55
59
|
const result = chain(ok('42'), parse) // ok(42)
|
|
56
60
|
```
|
|
57
61
|
|
|
62
|
+
### Content Hashing
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import { computeContentHash } from '@mikesaintsg/core'
|
|
66
|
+
|
|
67
|
+
const hash = await computeContentHash('Hello, world!')
|
|
68
|
+
// 'a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e'
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Tool Call Bridge
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import { createToolCallBridge } from '@mikesaintsg/core'
|
|
75
|
+
|
|
76
|
+
const bridge = createToolCallBridge({
|
|
77
|
+
registry,
|
|
78
|
+
timeout: 30000,
|
|
79
|
+
onError: (error, toolCall) => console.error(error),
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
// Execute single call
|
|
83
|
+
const result = await bridge.execute(toolCall)
|
|
84
|
+
|
|
85
|
+
// Execute multiple calls in parallel
|
|
86
|
+
const results = await bridge.execute([call1, call2, call3])
|
|
87
|
+
```
|
|
88
|
+
|
|
58
89
|
---
|
|
59
90
|
|
|
60
91
|
## Documentation
|
|
@@ -64,7 +95,6 @@ const result = chain(ok('42'), parse) // ok(42)
|
|
|
64
95
|
### Key Sections
|
|
65
96
|
|
|
66
97
|
- [Introduction](./guides/core.md#introduction) — Value proposition and use cases
|
|
67
|
-
- [Quick Start](./guides/core.md#quick-start) — Get started in minutes
|
|
68
98
|
- [Core Concepts](./guides/core.md#core-concepts) — Understand the fundamentals
|
|
69
99
|
- [Result Pattern](./guides/core.md#result-pattern) — Functional error handling
|
|
70
100
|
- [Bridge Interfaces](./guides/core.md#bridge-interfaces) — Cross-package communication
|
|
@@ -76,17 +106,33 @@ const result = chain(ok('42'), parse) // ok(42)
|
|
|
76
106
|
|
|
77
107
|
### Result Functions
|
|
78
108
|
|
|
79
|
-
| Function
|
|
80
|
-
|
|
81
|
-
| `ok(value)`
|
|
82
|
-
| `err(error)`
|
|
83
|
-
| `isOk(result)`
|
|
84
|
-
| `isErr(result)`
|
|
85
|
-
| `unwrap(result, default)`
|
|
86
|
-
| `
|
|
87
|
-
| `
|
|
109
|
+
| Function | Description |
|
|
110
|
+
|------------------------------|------------------------------|
|
|
111
|
+
| `ok(value)` | Create a success result |
|
|
112
|
+
| `err(error)` | Create a failure result |
|
|
113
|
+
| `isOk(result)` | Check if result is success |
|
|
114
|
+
| `isErr(result)` | Check if result is failure |
|
|
115
|
+
| `unwrap(result, default)` | Get value or default |
|
|
116
|
+
| `unwrapOrThrow(result)` | Get value or throw error |
|
|
117
|
+
| `map(result, fn)` | Transform success value |
|
|
118
|
+
| `mapErr(result, fn)` | Transform error value |
|
|
119
|
+
| `chain(result, fn)` | Chain results (flatMap) |
|
|
120
|
+
|
|
121
|
+
### Content Hashing
|
|
88
122
|
|
|
89
|
-
|
|
123
|
+
| Function | Description |
|
|
124
|
+
|------------------------------|------------------------------|
|
|
125
|
+
| `computeContentHash(text)` | SHA-256 hash for text |
|
|
126
|
+
|
|
127
|
+
### Bridge Helper Functions
|
|
128
|
+
|
|
129
|
+
| Function | Description |
|
|
130
|
+
|------------------------------|-----------------------------------|
|
|
131
|
+
| `isToolCall(value)` | Type guard for ToolCall objects |
|
|
132
|
+
| `shouldSkipFormGuard(...)` | Check if form guard should skip |
|
|
133
|
+
| `formatScoredResult(result)` | Default result formatter |
|
|
134
|
+
|
|
135
|
+
### Factory Functions
|
|
90
136
|
|
|
91
137
|
| Function | Description |
|
|
92
138
|
|-------------------------------------|----------------------------------|
|
|
@@ -95,15 +141,57 @@ const result = chain(ok('42'), parse) // ok(42)
|
|
|
95
141
|
| `createFormDirtyGuard(options)` | Navigation guard for dirty forms |
|
|
96
142
|
| `createSessionPersistence(options)` | Session storage adapter |
|
|
97
143
|
|
|
144
|
+
### Error Handling
|
|
145
|
+
|
|
146
|
+
| Export | Description |
|
|
147
|
+
|------------------------|------------------------------------|
|
|
148
|
+
| `EcosystemError` | Base error class for all packages |
|
|
149
|
+
| `isEcosystemError(e)` | Type guard for ecosystem errors |
|
|
150
|
+
|
|
98
151
|
### Shared Types
|
|
99
152
|
|
|
100
|
-
| Type
|
|
101
|
-
|
|
102
|
-
| `Result<T, E>`
|
|
103
|
-
| `
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
153
|
+
| Type | Description |
|
|
154
|
+
|-------------------------------------------|---------------------------------------|
|
|
155
|
+
| `Result<T, E>` | Success or failure union |
|
|
156
|
+
| `Ok<T>`, `Err<E>` | Result discriminants |
|
|
157
|
+
| `Unsubscribe` | Cleanup function type |
|
|
158
|
+
| `DestroyFn` | Resource cleanup function |
|
|
159
|
+
| `SubscriptionToHook<T>` | Convert subscriptions to hooks |
|
|
160
|
+
| `Embedding` | Float32Array embedding vector |
|
|
161
|
+
| `ToolCall`, `ToolResult`, `ToolSchema` | Tool-related types |
|
|
162
|
+
| `ScoredResult` | Search result with score |
|
|
163
|
+
| `ContextFrame`, `BuiltContext` | Context management types |
|
|
164
|
+
| `TokenBudgetState`, `TokenBudgetLevel` | Token budget types |
|
|
165
|
+
|
|
166
|
+
### Adapter Interfaces
|
|
167
|
+
|
|
168
|
+
| Interface | Category | Description |
|
|
169
|
+
|-------------------------------------------|---------------|--------------------------------|
|
|
170
|
+
| `EmbeddingAdapterInterface` | Source | Embedding generation |
|
|
171
|
+
| `ToolFormatAdapterInterface` | Transform | Provider tool formatting |
|
|
172
|
+
| `SimilarityAdapterInterface` | Transform | Vector similarity computation |
|
|
173
|
+
| `DeduplicationAdapterInterface` | Transform | Frame deduplication |
|
|
174
|
+
| `TruncationAdapterInterface` | Transform | Context truncation |
|
|
175
|
+
| `PriorityAdapterInterface` | Transform | Frame priority ordering |
|
|
176
|
+
| `RetryAdapterInterface` | Policy | Retry behavior |
|
|
177
|
+
| `RateLimitAdapterInterface` | Policy | Rate limiting |
|
|
178
|
+
| `EmbeddingCacheAdapterInterface` | Enhancement | Embedding caching |
|
|
179
|
+
| `BatchAdapterInterface` | Enhancement | Batch processing |
|
|
180
|
+
| `RerankerAdapterInterface` | Enhancement | Result reranking |
|
|
181
|
+
| `VectorStorePersistenceAdapterInterface` | Persistence | Vector storage |
|
|
182
|
+
|
|
183
|
+
### Minimal Cross-Package Interfaces
|
|
184
|
+
|
|
185
|
+
| Interface | Description |
|
|
186
|
+
|-----------------------------|--------------------------------------|
|
|
187
|
+
| `MinimalDatabaseAccess<T>` | IndexedDB access without dependency |
|
|
188
|
+
| `MinimalStoreAccess<T>` | Store operations interface |
|
|
189
|
+
| `MinimalDirectoryAccess` | OPFS directory access |
|
|
190
|
+
| `MinimalFileAccess` | OPFS file access |
|
|
191
|
+
| `ToolRegistryMinimal` | Tool registry without dependency |
|
|
192
|
+
| `VectorStoreMinimal<T>` | Vector store without dependency |
|
|
193
|
+
| `FormMinimal<T>` | Form state without dependency |
|
|
194
|
+
| `SerializableSession` | Session serialization interface |
|
|
107
195
|
|
|
108
196
|
---
|
|
109
197
|
|
|
@@ -112,7 +200,7 @@ const result = chain(ok('42'), parse) // ok(42)
|
|
|
112
200
|
### Result Pattern
|
|
113
201
|
|
|
114
202
|
```ts
|
|
115
|
-
import { ok, err, isOk, unwrap } from '@mikesaintsg/core'
|
|
203
|
+
import { ok, err, isOk, unwrap, map, chain } from '@mikesaintsg/core'
|
|
116
204
|
|
|
117
205
|
function divide(a: number, b: number) {
|
|
118
206
|
if (b === 0) return err('DIVISION_BY_ZERO')
|
|
@@ -121,52 +209,109 @@ function divide(a: number, b: number) {
|
|
|
121
209
|
|
|
122
210
|
const result = divide(10, 2)
|
|
123
211
|
const value = unwrap(result, 0) // 5
|
|
212
|
+
|
|
213
|
+
// Chain operations
|
|
214
|
+
const doubled = chain(divide(10, 2), n => ok(n * 2)) // ok(10)
|
|
124
215
|
```
|
|
125
216
|
|
|
126
|
-
###
|
|
217
|
+
### Custom Error Class
|
|
127
218
|
|
|
128
219
|
```ts
|
|
129
|
-
import {
|
|
220
|
+
import { EcosystemError, isEcosystemError } from '@mikesaintsg/core'
|
|
130
221
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
222
|
+
type StorageErrorCode = 'NOT_FOUND' | 'QUOTA_EXCEEDED' | 'WRITE_FAILED'
|
|
223
|
+
|
|
224
|
+
class StorageError extends EcosystemError {
|
|
225
|
+
readonly code: StorageErrorCode
|
|
226
|
+
|
|
227
|
+
constructor(code: StorageErrorCode, message: string, cause?: Error) {
|
|
228
|
+
super(message, cause)
|
|
229
|
+
this.code = code
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
try {
|
|
234
|
+
throw new StorageError('NOT_FOUND', 'Document not found')
|
|
235
|
+
} catch (error) {
|
|
236
|
+
if (isEcosystemError(error)) {
|
|
237
|
+
console.log(error.code) // 'NOT_FOUND'
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Retrieval Tool
|
|
243
|
+
|
|
244
|
+
```ts
|
|
245
|
+
import { createRetrievalTool } from '@mikesaintsg/core'
|
|
246
|
+
|
|
247
|
+
const { schema, handler } = createRetrievalTool({
|
|
248
|
+
vectorStore,
|
|
249
|
+
name: 'search_docs',
|
|
250
|
+
description: 'Search documentation for relevant information',
|
|
251
|
+
defaultLimit: 5,
|
|
252
|
+
scoreThreshold: 0.7,
|
|
135
253
|
})
|
|
136
254
|
|
|
137
|
-
|
|
255
|
+
// Register with tool registry
|
|
256
|
+
registry.register(schema, handler)
|
|
138
257
|
```
|
|
139
258
|
|
|
140
|
-
###
|
|
259
|
+
### Session Persistence
|
|
141
260
|
|
|
142
261
|
```ts
|
|
143
|
-
import
|
|
144
|
-
EmbeddingAdapterInterface,
|
|
145
|
-
Result
|
|
146
|
-
} from '@mikesaintsg/core'
|
|
262
|
+
import { createSessionPersistence } from '@mikesaintsg/core'
|
|
147
263
|
|
|
148
|
-
|
|
149
|
-
|
|
264
|
+
const persistence = createSessionPersistence({
|
|
265
|
+
database,
|
|
266
|
+
storeName: 'chat_sessions',
|
|
267
|
+
autoprune: 7 * 24 * 60 * 60 * 1000, // 7 days
|
|
268
|
+
})
|
|
150
269
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const n = parseInt(input, 10)
|
|
154
|
-
return isNaN(n) ? err('PARSE_ERROR') : ok(n)
|
|
155
|
-
}
|
|
270
|
+
await persistence.save('session-1', session)
|
|
271
|
+
const loaded = await persistence.load('session-1')
|
|
156
272
|
```
|
|
157
273
|
|
|
274
|
+
### Form Dirty Guard
|
|
275
|
+
|
|
276
|
+
```ts
|
|
277
|
+
import { createFormDirtyGuard } from '@mikesaintsg/core'
|
|
278
|
+
|
|
279
|
+
const guard = createFormDirtyGuard({
|
|
280
|
+
form,
|
|
281
|
+
confirmFn: (message) => window.confirm(message),
|
|
282
|
+
message: 'You have unsaved changes. Continue?',
|
|
283
|
+
excludePages: ['logout'],
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
router.beforeNavigate(guard)
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## Constants
|
|
292
|
+
|
|
293
|
+
| Constant | Value | Description |
|
|
294
|
+
|------------------------------|--------|--------------------------------|
|
|
295
|
+
| `BRIDGE_DEFAULT_TIMEOUT` | 30000 | Default bridge timeout (ms) |
|
|
296
|
+
| `RETRIEVAL_DEFAULT_LIMIT` | 10 | Default retrieval result limit |
|
|
297
|
+
| `RETRIEVAL_MAX_LIMIT` | 100 | Maximum retrieval result limit |
|
|
298
|
+
| `FORM_DIRTY_DEFAULT_MESSAGE` | string | Default form guard message |
|
|
299
|
+
|
|
158
300
|
---
|
|
159
301
|
|
|
160
302
|
## Ecosystem Integration
|
|
161
303
|
|
|
162
304
|
| Package | Integration |
|
|
163
305
|
|--------------------------------|------------------------------------------------|
|
|
164
|
-
| `@mikesaintsg/adapters` |
|
|
306
|
+
| `@mikesaintsg/adapters` | Implements adapter interfaces |
|
|
165
307
|
| `@mikesaintsg/inference` | Uses shared types and bridge functions |
|
|
166
308
|
| `@mikesaintsg/vectorstore` | Uses embedding and persistence interfaces |
|
|
167
309
|
| `@mikesaintsg/contextprotocol` | Uses tool types and registry interface |
|
|
310
|
+
| `@mikesaintsg/contextbuilder` | Uses context frame and budget types |
|
|
311
|
+
| `@mikesaintsg/indexeddb` | Implements MinimalDatabaseAccess |
|
|
312
|
+
| `@mikesaintsg/filesystem` | Implements MinimalDirectoryAccess |
|
|
168
313
|
|
|
169
|
-
See [Integration
|
|
314
|
+
See [Integration Guide](./guides/integration.md) for detailed patterns.
|
|
170
315
|
|
|
171
316
|
---
|
|
172
317
|
|
package/dist/index.d.ts
CHANGED
|
@@ -3,13 +3,17 @@ export declare interface AbortableOptions {
|
|
|
3
3
|
readonly signal?: AbortSignal;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Batch adapter interface.
|
|
8
|
+
* Controls batching behavior for bulk operations.
|
|
9
|
+
*/
|
|
10
|
+
export declare interface BatchAdapterInterface {
|
|
11
|
+
/** Maximum items per batch */
|
|
12
|
+
getBatchSize(): number;
|
|
13
|
+
/** Delay between batches (ms) */
|
|
14
|
+
getDelayMs(): number;
|
|
15
|
+
/** Whether to deduplicate items within a batch */
|
|
16
|
+
shouldDeduplicate(): boolean;
|
|
13
17
|
}
|
|
14
18
|
|
|
15
19
|
/** Default timeout for bridge operations in milliseconds */
|
|
@@ -26,6 +30,14 @@ export declare interface BuiltContext {
|
|
|
26
30
|
readonly timestamp: number;
|
|
27
31
|
}
|
|
28
32
|
|
|
33
|
+
/** Cache statistics */
|
|
34
|
+
export declare interface CacheStats {
|
|
35
|
+
readonly hits: number;
|
|
36
|
+
readonly misses: number;
|
|
37
|
+
readonly size: number;
|
|
38
|
+
readonly maxSize?: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
29
41
|
/**
|
|
30
42
|
* Chain results (flatMap). Apply a function that returns a Result to a success value.
|
|
31
43
|
*
|
|
@@ -76,26 +88,6 @@ export declare interface ContextFrame {
|
|
|
76
88
|
readonly metadata?: FrameMetadata;
|
|
77
89
|
}
|
|
78
90
|
|
|
79
|
-
/**
|
|
80
|
-
* Core package error.
|
|
81
|
-
*
|
|
82
|
-
* @example
|
|
83
|
-
* ```ts
|
|
84
|
-
* throw new CoreError('ADAPTER_ERROR', 'Failed to connect to OpenAI')
|
|
85
|
-
* ```
|
|
86
|
-
*/
|
|
87
|
-
export declare class CoreError extends Error {
|
|
88
|
-
readonly code: CoreErrorCode;
|
|
89
|
-
readonly cause: Error | undefined;
|
|
90
|
-
constructor(code: CoreErrorCode, message: string, cause?: Error);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/** Core package error codes */
|
|
94
|
-
export declare type CoreErrorCode = 'ADAPTER_ERROR' | 'BRIDGE_ERROR' | 'VALIDATION_ERROR' | 'NOT_FOUND' | 'TIMEOUT' | 'ABORTED';
|
|
95
|
-
|
|
96
|
-
/** Factory function for creating embedding cache */
|
|
97
|
-
export declare type CreateEmbeddingCache = (options?: EmbeddingCacheOptions) => EmbeddingCacheInterface;
|
|
98
|
-
|
|
99
91
|
/**
|
|
100
92
|
* Create a navigation guard that prevents leaving when form is dirty.
|
|
101
93
|
*
|
|
@@ -198,11 +190,23 @@ export declare function createSessionPersistence(options: SessionPersistenceOpti
|
|
|
198
190
|
* })
|
|
199
191
|
*
|
|
200
192
|
* // Execute tool calls from LLM response
|
|
201
|
-
* const results = await bridge.
|
|
193
|
+
* const results = await bridge.execute(response.toolCalls)
|
|
202
194
|
* ```
|
|
203
195
|
*/
|
|
204
196
|
export declare function createToolCallBridge(options: ToolCallBridgeOptions): ToolCallBridgeInterface;
|
|
205
197
|
|
|
198
|
+
/**
|
|
199
|
+
* Deduplication adapter interface.
|
|
200
|
+
* Determines how to handle duplicate frames based on content hash.
|
|
201
|
+
* Implemented in @mikesaintsg/adapters.
|
|
202
|
+
*/
|
|
203
|
+
export declare interface DeduplicationAdapterInterface {
|
|
204
|
+
/** Select which frame to keep from duplicates with the same content hash */
|
|
205
|
+
select(frames: readonly ContextFrame[]): ContextFrame;
|
|
206
|
+
/** Check if a frame should be preserved regardless of deduplication */
|
|
207
|
+
shouldPreserve(frame: ContextFrame): boolean;
|
|
208
|
+
}
|
|
209
|
+
|
|
206
210
|
/** Deduplication result summary */
|
|
207
211
|
export declare interface DeduplicationResult {
|
|
208
212
|
readonly originalCount: number;
|
|
@@ -212,73 +216,87 @@ export declare interface DeduplicationResult {
|
|
|
212
216
|
readonly tokensSaved: number;
|
|
213
217
|
}
|
|
214
218
|
|
|
219
|
+
/** Deduplication strategy for default adapter */
|
|
220
|
+
export declare type DeduplicationStrategy = 'keep_latest' | 'keep_first' | 'keep_highest_priority' | 'merge';
|
|
221
|
+
|
|
222
|
+
/** Resource that must be explicitly destroyed */
|
|
223
|
+
export declare interface Destroyable {
|
|
224
|
+
/** Release all resources held by this instance. After calling, the instance is unusable. */
|
|
225
|
+
destroy(): void;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* @mikesaintsg/core
|
|
230
|
+
*
|
|
231
|
+
* Base error class and utilities for the ecosystem.
|
|
232
|
+
*/
|
|
215
233
|
/**
|
|
216
234
|
* Base error class for all ecosystem errors.
|
|
217
235
|
* All package-specific errors should extend this class.
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```ts
|
|
239
|
+
* class StorageError extends EcosystemError {
|
|
240
|
+
* readonly code: StorageErrorCode
|
|
241
|
+
*
|
|
242
|
+
* constructor(code: StorageErrorCode, message: string, cause?: Error) {
|
|
243
|
+
* super(message, cause)
|
|
244
|
+
* this.code = code
|
|
245
|
+
* }
|
|
246
|
+
* }
|
|
247
|
+
* ```
|
|
218
248
|
*/
|
|
219
249
|
export declare abstract class EcosystemError extends Error {
|
|
250
|
+
/** Error code for programmatic handling */
|
|
220
251
|
abstract readonly code: string;
|
|
252
|
+
/** Original error that caused this one */
|
|
221
253
|
readonly cause: Error | undefined;
|
|
222
254
|
constructor(message: string, cause?: Error);
|
|
223
255
|
}
|
|
224
256
|
|
|
225
|
-
/**
|
|
257
|
+
/** A single embedding vector. Float32Array for memory efficiency and typed array operations. */
|
|
226
258
|
export declare type Embedding = Float32Array;
|
|
227
259
|
|
|
228
|
-
/**
|
|
260
|
+
/**
|
|
261
|
+
* Contract for embedding generation.
|
|
262
|
+
* Implemented by adapters, consumed by vectorstore.
|
|
263
|
+
*/
|
|
229
264
|
export declare interface EmbeddingAdapterInterface {
|
|
265
|
+
/**
|
|
266
|
+
* Generate embeddings for one or more texts.
|
|
267
|
+
* @param texts - Texts to embed
|
|
268
|
+
* @param options - Optional abort signal
|
|
269
|
+
* @returns Embeddings in same order as input texts
|
|
270
|
+
*/
|
|
230
271
|
embed(texts: readonly string[], options?: AbortableOptions): Promise<readonly Embedding[]>;
|
|
272
|
+
/** Get metadata about the embedding model. Used for compatibility checking. */
|
|
231
273
|
getModelMetadata(): EmbeddingModelMetadata;
|
|
232
274
|
}
|
|
233
275
|
|
|
234
|
-
/**
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
readonly modelId: string;
|
|
247
|
-
readonly createdAt: number;
|
|
248
|
-
readonly hitCount: number;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/** Embedding cache interface */
|
|
252
|
-
export declare interface EmbeddingCacheInterface {
|
|
253
|
-
get(contentHash: ContentHash): Embedding | undefined;
|
|
254
|
-
set(contentHash: ContentHash, embedding: Embedding): void;
|
|
255
|
-
has(contentHash: ContentHash): boolean;
|
|
256
|
-
remove(contentHash: ContentHash): boolean;
|
|
276
|
+
/**
|
|
277
|
+
* Embedding cache adapter interface.
|
|
278
|
+
* Provides caching for embedding operations.
|
|
279
|
+
*/
|
|
280
|
+
export declare interface EmbeddingCacheAdapterInterface {
|
|
281
|
+
/** Get cached embedding for text */
|
|
282
|
+
get(text: string): Embedding | undefined;
|
|
283
|
+
/** Store embedding in cache */
|
|
284
|
+
set(text: string, embedding: Embedding): void;
|
|
285
|
+
/** Check if text is cached */
|
|
286
|
+
has(text: string): boolean;
|
|
287
|
+
/** Clear all cached embeddings */
|
|
257
288
|
clear(): void;
|
|
258
|
-
|
|
289
|
+
/** Optional: Get cache statistics */
|
|
290
|
+
getStats?(): CacheStats;
|
|
259
291
|
}
|
|
260
292
|
|
|
261
|
-
/**
|
|
262
|
-
export declare interface EmbeddingCacheOptions {
|
|
263
|
-
readonly maxEntries?: number;
|
|
264
|
-
readonly maxBytes?: number;
|
|
265
|
-
readonly ttlMs?: number;
|
|
266
|
-
readonly onEvict?: (contentHash: ContentHash, embedding: Embedding) => void;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/** Embedding cache statistics */
|
|
270
|
-
export declare interface EmbeddingCacheStats {
|
|
271
|
-
readonly entries: number;
|
|
272
|
-
readonly hits: number;
|
|
273
|
-
readonly misses: number;
|
|
274
|
-
readonly hitRate: number;
|
|
275
|
-
readonly estimatedBytes: number;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
/** Embedding model info */
|
|
293
|
+
/** Metadata identifying an embedding model. Used to ensure vector compatibility. */
|
|
279
294
|
export declare interface EmbeddingModelMetadata {
|
|
295
|
+
/** Provider name (e.g., 'openai', 'anthropic') */
|
|
280
296
|
readonly provider: string;
|
|
297
|
+
/** Model identifier (e.g., 'text-embedding-3-small') */
|
|
281
298
|
readonly model: string;
|
|
299
|
+
/** Vector dimensions produced by this model */
|
|
282
300
|
readonly dimensions: number;
|
|
283
301
|
}
|
|
284
302
|
|
|
@@ -303,12 +321,23 @@ export declare interface Err<E> {
|
|
|
303
321
|
*/
|
|
304
322
|
export declare function err<E>(error: E): Err<E>;
|
|
305
323
|
|
|
306
|
-
/** Extract error code type */
|
|
307
|
-
export declare type ErrorCode<T extends
|
|
324
|
+
/** Extract error code type from an error class */
|
|
325
|
+
export declare type ErrorCode<T extends {
|
|
326
|
+
readonly code: string;
|
|
327
|
+
}> = T['code'];
|
|
308
328
|
|
|
309
329
|
/** Default form dirty guard message */
|
|
310
330
|
export declare const FORM_DIRTY_DEFAULT_MESSAGE = "You have unsaved changes. Are you sure you want to leave?";
|
|
311
331
|
|
|
332
|
+
/**
|
|
333
|
+
* Default result formatter for retrieval tools.
|
|
334
|
+
* Returns content, score, and metadata.
|
|
335
|
+
*
|
|
336
|
+
* @param result - Scored result to format
|
|
337
|
+
* @returns Formatted result object
|
|
338
|
+
*/
|
|
339
|
+
export declare function formatScoredResult(result: ScoredResult): unknown;
|
|
340
|
+
|
|
312
341
|
/** Form dirty guard options */
|
|
313
342
|
export declare interface FormDirtyGuardOptions<TFormData = unknown, TPage extends string = string> {
|
|
314
343
|
readonly form: FormMinimal<TFormData>;
|
|
@@ -352,54 +381,6 @@ export declare interface FrameSummary {
|
|
|
352
381
|
/** Frame type discriminator */
|
|
353
382
|
export declare type FrameType = 'system' | 'instruction' | 'section' | 'file' | 'document' | 'example' | 'tool' | 'memory' | 'retrieval' | 'custom';
|
|
354
383
|
|
|
355
|
-
/** Generation defaults for provider adapters */
|
|
356
|
-
export declare interface GenerationDefaults {
|
|
357
|
-
readonly model?: string;
|
|
358
|
-
readonly temperature?: number;
|
|
359
|
-
readonly maxTokens?: number;
|
|
360
|
-
readonly topP?: number;
|
|
361
|
-
readonly stop?: readonly string[];
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
/** HTTP persistence options */
|
|
365
|
-
export declare interface HTTPPersistenceOptions {
|
|
366
|
-
readonly baseURL: string;
|
|
367
|
-
readonly headers?: Readonly<Record<string, string>>;
|
|
368
|
-
readonly timeout?: number;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
/** IndexedDB VectorStore persistence options */
|
|
372
|
-
export declare interface IndexedDBVectorStorePersistenceOptions {
|
|
373
|
-
readonly database: MinimalDatabaseAccess;
|
|
374
|
-
readonly documentsStore?: string;
|
|
375
|
-
readonly metadataStore?: string;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
/** In-memory embedding cache options */
|
|
379
|
-
export declare interface InMemoryEmbeddingCacheOptions {
|
|
380
|
-
readonly maxEntries?: number;
|
|
381
|
-
readonly ttlMs?: number;
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
/**
|
|
385
|
-
* Type guard to check if an error is a CoreError.
|
|
386
|
-
*
|
|
387
|
-
* @param error - The value to check
|
|
388
|
-
* @returns True if the error is a CoreError
|
|
389
|
-
*
|
|
390
|
-
* @example
|
|
391
|
-
* ```ts
|
|
392
|
-
* try {
|
|
393
|
-
* await adapter.embed(['text'])
|
|
394
|
-
* } catch (error) {
|
|
395
|
-
* if (isCoreError(error)) {
|
|
396
|
-
* console.log('Code:', error.code)
|
|
397
|
-
* }
|
|
398
|
-
* }
|
|
399
|
-
* ```
|
|
400
|
-
*/
|
|
401
|
-
export declare function isCoreError(error: unknown): error is CoreError;
|
|
402
|
-
|
|
403
384
|
/**
|
|
404
385
|
* Type guard for ecosystem errors.
|
|
405
386
|
*
|
|
@@ -451,6 +432,18 @@ export declare function isErr<T, E>(result: Result<T, E>): result is Err<E>;
|
|
|
451
432
|
*/
|
|
452
433
|
export declare function isOk<T, E>(result: Result<T, E>): result is Ok<T>;
|
|
453
434
|
|
|
435
|
+
/**
|
|
436
|
+
* Check if a value is a single ToolCall (not an array).
|
|
437
|
+
*
|
|
438
|
+
* @param value - Value to check
|
|
439
|
+
* @returns True if the value is a single ToolCall
|
|
440
|
+
*/
|
|
441
|
+
export declare function isToolCall(value: unknown): value is {
|
|
442
|
+
id: string;
|
|
443
|
+
name: string;
|
|
444
|
+
arguments: unknown;
|
|
445
|
+
};
|
|
446
|
+
|
|
454
447
|
/** JSON Schema 7 subset for tool parameters */
|
|
455
448
|
export declare interface JSONSchema7 {
|
|
456
449
|
readonly type?: string | readonly string[];
|
|
@@ -507,7 +500,7 @@ export declare function mapErr<T, E, F>(result: Result<T, E>, fn: (error: E) =>
|
|
|
507
500
|
|
|
508
501
|
/**
|
|
509
502
|
* Minimal database access interface for cross-package adapters.
|
|
510
|
-
* Used by
|
|
503
|
+
* Used by persistence adapters to access IndexedDB without
|
|
511
504
|
* creating a hard dependency on the indexeddb package.
|
|
512
505
|
*/
|
|
513
506
|
export declare interface MinimalDatabaseAccess<T = unknown> {
|
|
@@ -516,7 +509,7 @@ export declare interface MinimalDatabaseAccess<T = unknown> {
|
|
|
516
509
|
|
|
517
510
|
/**
|
|
518
511
|
* Minimal directory access interface for cross-package adapters.
|
|
519
|
-
* Used by
|
|
512
|
+
* Used by OPFS persistence adapters without creating
|
|
520
513
|
* a hard dependency on the filesystem package.
|
|
521
514
|
*/
|
|
522
515
|
export declare interface MinimalDirectoryAccess {
|
|
@@ -576,15 +569,9 @@ export declare interface Ok<T> {
|
|
|
576
569
|
*/
|
|
577
570
|
export declare function ok<T>(value: T): Ok<T>;
|
|
578
571
|
|
|
579
|
-
/** OPFS VectorStore persistence options */
|
|
580
|
-
export declare interface OPFSVectorStorePersistenceOptions {
|
|
581
|
-
readonly directory: MinimalDirectoryAccess;
|
|
582
|
-
readonly chunkSize?: number;
|
|
583
|
-
}
|
|
584
|
-
|
|
585
572
|
/**
|
|
586
573
|
* Generic error data interface for package-specific errors.
|
|
587
|
-
*
|
|
574
|
+
* Packages extend this to define their error structure.
|
|
588
575
|
*
|
|
589
576
|
* @example
|
|
590
577
|
* ```ts
|
|
@@ -599,13 +586,16 @@ export declare interface PackageErrorData<TCode extends string> {
|
|
|
599
586
|
readonly cause?: Error;
|
|
600
587
|
}
|
|
601
588
|
|
|
602
|
-
/**
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
589
|
+
/**
|
|
590
|
+
* Priority adapter interface.
|
|
591
|
+
* Provides priority weights and comparison logic.
|
|
592
|
+
* Implemented in @mikesaintsg/adapters.
|
|
593
|
+
*/
|
|
594
|
+
export declare interface PriorityAdapterInterface {
|
|
595
|
+
/** Get numeric weight for a priority level. Higher values = more important. */
|
|
596
|
+
getWeight(priority: FramePriority): number;
|
|
597
|
+
/** Compare two frames by priority */
|
|
598
|
+
compare(a: ContextFrame, b: ContextFrame): number;
|
|
609
599
|
}
|
|
610
600
|
|
|
611
601
|
/** Prune result information */
|
|
@@ -614,7 +604,42 @@ export declare interface PruneResult {
|
|
|
614
604
|
readonly remainingCount: number;
|
|
615
605
|
}
|
|
616
606
|
|
|
617
|
-
/**
|
|
607
|
+
/**
|
|
608
|
+
* Rate limit adapter interface.
|
|
609
|
+
* Controls request rate to external services.
|
|
610
|
+
*/
|
|
611
|
+
export declare interface RateLimitAdapterInterface {
|
|
612
|
+
/** Acquire a request slot, waits if none available */
|
|
613
|
+
acquire(): Promise<void>;
|
|
614
|
+
/** Release a request slot */
|
|
615
|
+
release(): void;
|
|
616
|
+
/** Get current rate limit state */
|
|
617
|
+
getState(): RateLimitState;
|
|
618
|
+
/** Dynamically adjust rate limit (e.g., from Retry-After header) */
|
|
619
|
+
setLimit(requestsPerMinute: number): void;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
/** Rate limit state */
|
|
623
|
+
export declare interface RateLimitState {
|
|
624
|
+
readonly activeRequests: number;
|
|
625
|
+
readonly maxConcurrent: number;
|
|
626
|
+
readonly requestsInWindow: number;
|
|
627
|
+
readonly requestsPerMinute: number;
|
|
628
|
+
readonly windowResetIn: number;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* Reranker adapter interface.
|
|
633
|
+
* Reranks search results using a cross-encoder or similar model.
|
|
634
|
+
*/
|
|
635
|
+
export declare interface RerankerAdapterInterface {
|
|
636
|
+
/** Rerank documents for a given query */
|
|
637
|
+
rerank(query: string, docs: readonly ScoredResult[]): Promise<readonly ScoredResult[]>;
|
|
638
|
+
/** Get the model ID used for reranking */
|
|
639
|
+
getModelId(): string;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/** Result union - discriminated union for operation results */
|
|
618
643
|
export declare type Result<T, E> = Ok<T> | Err<E>;
|
|
619
644
|
|
|
620
645
|
/** Default retrieval limit for retrieval tool */
|
|
@@ -642,6 +667,21 @@ export declare interface RetrievalToolOptions<TMetadata = unknown> {
|
|
|
642
667
|
readonly buildFilter?: (params: Readonly<Record<string, unknown>>) => TMetadata | undefined;
|
|
643
668
|
}
|
|
644
669
|
|
|
670
|
+
/**
|
|
671
|
+
* Retry adapter interface.
|
|
672
|
+
* Determines retry behavior for failed operations.
|
|
673
|
+
*/
|
|
674
|
+
export declare interface RetryAdapterInterface {
|
|
675
|
+
/** Determine if an error should trigger a retry */
|
|
676
|
+
shouldRetry(error: unknown, attempt: number): boolean;
|
|
677
|
+
/** Get delay before next retry attempt (ms) */
|
|
678
|
+
getDelay(attempt: number): number;
|
|
679
|
+
/** Maximum number of retry attempts */
|
|
680
|
+
getMaxAttempts(): number;
|
|
681
|
+
/** Optional callback before each retry */
|
|
682
|
+
onRetry?(error: unknown, attempt: number, delayMs: number): void;
|
|
683
|
+
}
|
|
684
|
+
|
|
645
685
|
/** Scored result from similarity search or retrieval */
|
|
646
686
|
export declare interface ScoredResult {
|
|
647
687
|
readonly id: string;
|
|
@@ -704,6 +744,28 @@ export declare interface SessionPersistenceOptions {
|
|
|
704
744
|
readonly onSaveError?: (error: unknown, sessionId: string) => void;
|
|
705
745
|
}
|
|
706
746
|
|
|
747
|
+
/**
|
|
748
|
+
* Determine if form dirty guard should be skipped for a navigation.
|
|
749
|
+
*
|
|
750
|
+
* @param to - Target page
|
|
751
|
+
* @param from - Source page
|
|
752
|
+
* @param excludePages - Pages to exclude from guard
|
|
753
|
+
* @param onlyFromPages - Only guard from these pages (if specified)
|
|
754
|
+
* @returns True if guard should be skipped
|
|
755
|
+
*/
|
|
756
|
+
export declare function shouldSkipFormGuard<TPage extends string>(to: TPage, from: TPage, excludePages: readonly TPage[], onlyFromPages: readonly TPage[] | undefined): boolean;
|
|
757
|
+
|
|
758
|
+
/**
|
|
759
|
+
* Similarity adapter interface.
|
|
760
|
+
* Computes similarity between embedding vectors.
|
|
761
|
+
*/
|
|
762
|
+
export declare interface SimilarityAdapterInterface {
|
|
763
|
+
/** Compute similarity score between two embeddings */
|
|
764
|
+
compute(a: Embedding, b: Embedding): number;
|
|
765
|
+
/** Name of the similarity function */
|
|
766
|
+
readonly name: string;
|
|
767
|
+
}
|
|
768
|
+
|
|
707
769
|
/** Storage information (quota and usage) */
|
|
708
770
|
export declare interface StorageInfo {
|
|
709
771
|
readonly usage: number;
|
|
@@ -745,7 +807,7 @@ export declare interface TokenBudgetState {
|
|
|
745
807
|
export declare interface ToolCall {
|
|
746
808
|
readonly id: string;
|
|
747
809
|
readonly name: string;
|
|
748
|
-
readonly arguments: Record<string, unknown
|
|
810
|
+
readonly arguments: Readonly<Record<string, unknown>>;
|
|
749
811
|
}
|
|
750
812
|
|
|
751
813
|
/**
|
|
@@ -753,8 +815,15 @@ export declare interface ToolCall {
|
|
|
753
815
|
* Connects inference tool calls to contextprotocol tool registry.
|
|
754
816
|
*/
|
|
755
817
|
export declare interface ToolCallBridgeInterface {
|
|
756
|
-
|
|
757
|
-
|
|
818
|
+
/**
|
|
819
|
+
* Execute tool call(s).
|
|
820
|
+
* Accepts single call or array of calls.
|
|
821
|
+
* @param toolCalls - Single tool call or array of calls
|
|
822
|
+
* @returns Single result or array of results
|
|
823
|
+
*/
|
|
824
|
+
execute(toolCalls: ToolCall): Promise<ToolResult>;
|
|
825
|
+
execute(toolCalls: readonly ToolCall[]): Promise<readonly ToolResult[]>;
|
|
826
|
+
/** Check if tool exists */
|
|
758
827
|
hasTool(name: string): boolean;
|
|
759
828
|
}
|
|
760
829
|
|
|
@@ -773,8 +842,11 @@ export declare interface ToolCallBridgeOptions {
|
|
|
773
842
|
* Implemented in @mikesaintsg/adapters.
|
|
774
843
|
*/
|
|
775
844
|
export declare interface ToolFormatAdapterInterface {
|
|
845
|
+
/** Convert tool schemas to provider-specific format */
|
|
776
846
|
formatSchemas(schemas: readonly ToolSchema[]): unknown;
|
|
847
|
+
/** Parse tool calls from provider response */
|
|
777
848
|
parseToolCalls(response: unknown): readonly ToolCall[];
|
|
849
|
+
/** Format tool result for provider */
|
|
778
850
|
formatResult(result: ToolResult): unknown;
|
|
779
851
|
}
|
|
780
852
|
|
|
@@ -804,6 +876,18 @@ export declare interface ToolSchema {
|
|
|
804
876
|
readonly returns?: JSONSchema7;
|
|
805
877
|
}
|
|
806
878
|
|
|
879
|
+
/**
|
|
880
|
+
* Truncation adapter interface.
|
|
881
|
+
* Determines which frames to remove when budget is exceeded.
|
|
882
|
+
* Implemented in @mikesaintsg/adapters.
|
|
883
|
+
*/
|
|
884
|
+
export declare interface TruncationAdapterInterface {
|
|
885
|
+
/** Sort frames for truncation order. Frames at the end are removed first. */
|
|
886
|
+
sort(frames: readonly ContextFrame[]): readonly ContextFrame[];
|
|
887
|
+
/** Check if a frame should be preserved regardless of truncation */
|
|
888
|
+
shouldPreserve(frame: ContextFrame): boolean;
|
|
889
|
+
}
|
|
890
|
+
|
|
807
891
|
/** Truncation information */
|
|
808
892
|
export declare interface TruncationInfo {
|
|
809
893
|
readonly originalFrameCount: number;
|
|
@@ -818,6 +902,13 @@ export declare type TruncationReason = 'budget_exceeded' | 'priority_too_low' |
|
|
|
818
902
|
/** Truncation strategy */
|
|
819
903
|
export declare type TruncationStrategy = 'priority' | 'fifo' | 'lifo' | 'score' | 'custom';
|
|
820
904
|
|
|
905
|
+
/**
|
|
906
|
+
* @mikesaintsg/core
|
|
907
|
+
*
|
|
908
|
+
* Shared type definitions for the @mikesaintsg ecosystem.
|
|
909
|
+
* Contains ONLY types and interfaces — no implementations.
|
|
910
|
+
* All public types and interfaces are defined here as the SOURCE OF TRUTH.
|
|
911
|
+
*/
|
|
821
912
|
/** Cleanup function returned by event subscriptions */
|
|
822
913
|
export declare type Unsubscribe = () => void;
|
|
823
914
|
|
package/dist/index.js
CHANGED
|
@@ -1,35 +1,26 @@
|
|
|
1
|
-
class x extends Error {
|
|
2
|
-
cause;
|
|
3
|
-
constructor(t, o) {
|
|
4
|
-
super(t), this.name = this.constructor.name, this.cause = o;
|
|
5
|
-
}
|
|
6
|
-
}
|
|
7
|
-
function F(e) {
|
|
8
|
-
return e instanceof x;
|
|
9
|
-
}
|
|
10
1
|
class A extends Error {
|
|
11
|
-
|
|
2
|
+
/** Original error that caused this one */
|
|
12
3
|
cause;
|
|
13
|
-
constructor(t,
|
|
14
|
-
super(
|
|
4
|
+
constructor(t, s) {
|
|
5
|
+
super(t), this.name = this.constructor.name, this.cause = s;
|
|
15
6
|
}
|
|
16
7
|
}
|
|
17
|
-
function
|
|
8
|
+
function b(e) {
|
|
18
9
|
return e instanceof A;
|
|
19
10
|
}
|
|
20
11
|
function S(e) {
|
|
21
12
|
return { ok: !0, value: e };
|
|
22
13
|
}
|
|
23
|
-
function
|
|
14
|
+
function l(e) {
|
|
24
15
|
return { ok: !1, error: e };
|
|
25
16
|
}
|
|
26
|
-
function
|
|
17
|
+
function F(e) {
|
|
27
18
|
return e.ok === !0;
|
|
28
19
|
}
|
|
29
|
-
function
|
|
20
|
+
function P(e) {
|
|
30
21
|
return !e.ok;
|
|
31
22
|
}
|
|
32
|
-
function
|
|
23
|
+
function q(e, t) {
|
|
33
24
|
return e.ok ? e.value : t;
|
|
34
25
|
}
|
|
35
26
|
function U(e) {
|
|
@@ -41,23 +32,36 @@ function B(e, t) {
|
|
|
41
32
|
return e.ok ? S(t(e.value)) : e;
|
|
42
33
|
}
|
|
43
34
|
function G(e, t) {
|
|
44
|
-
return e.ok ? e :
|
|
35
|
+
return e.ok ? e : l(t(e.error));
|
|
45
36
|
}
|
|
46
|
-
function
|
|
37
|
+
function O(e, t) {
|
|
47
38
|
return e.ok ? t(e.value) : e;
|
|
48
39
|
}
|
|
49
|
-
async function
|
|
50
|
-
const
|
|
51
|
-
return Array.from(new Uint8Array(
|
|
40
|
+
async function $(e) {
|
|
41
|
+
const s = new TextEncoder().encode(e), a = await crypto.subtle.digest("SHA-256", s);
|
|
42
|
+
return Array.from(new Uint8Array(a)).map((o) => o.toString(16).padStart(2, "0")).join("");
|
|
52
43
|
}
|
|
53
|
-
|
|
54
|
-
|
|
44
|
+
function I(e) {
|
|
45
|
+
return typeof e == "object" && e !== null && "id" in e && "name" in e && "arguments" in e;
|
|
46
|
+
}
|
|
47
|
+
function k(e, t, s, a) {
|
|
48
|
+
return !!(s.includes(e) || a !== void 0 && !a.includes(t));
|
|
49
|
+
}
|
|
50
|
+
function M(e) {
|
|
51
|
+
return {
|
|
52
|
+
content: e.content,
|
|
53
|
+
score: e.score,
|
|
54
|
+
metadata: e.metadata
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const R = 3e4, L = 10, _ = 100, D = "You have unsaved changes. Are you sure you want to leave?";
|
|
58
|
+
function j(e) {
|
|
55
59
|
const {
|
|
56
60
|
registry: t,
|
|
57
|
-
timeout:
|
|
58
|
-
onError:
|
|
59
|
-
onBeforeExecute:
|
|
60
|
-
onAfterExecute:
|
|
61
|
+
timeout: s = R,
|
|
62
|
+
onError: a,
|
|
63
|
+
onBeforeExecute: c,
|
|
64
|
+
onAfterExecute: o
|
|
61
65
|
} = e;
|
|
62
66
|
async function u(r) {
|
|
63
67
|
if (!t.has(r.name))
|
|
@@ -67,40 +71,37 @@ function H(e) {
|
|
|
67
71
|
success: !1,
|
|
68
72
|
error: `Tool not found: ${r.name}`
|
|
69
73
|
};
|
|
70
|
-
|
|
74
|
+
c?.(r);
|
|
71
75
|
try {
|
|
72
76
|
const n = new Promise((f, m) => {
|
|
73
77
|
setTimeout(() => {
|
|
74
|
-
m(new Error(`Tool execution timed out after ${
|
|
75
|
-
},
|
|
76
|
-
}),
|
|
78
|
+
m(new Error(`Tool execution timed out after ${s}ms`));
|
|
79
|
+
}, s);
|
|
80
|
+
}), i = await Promise.race([
|
|
77
81
|
t.execute(r.name, r.arguments),
|
|
78
82
|
n
|
|
79
83
|
]);
|
|
80
|
-
return
|
|
84
|
+
return o?.(r, i), {
|
|
81
85
|
callId: r.id,
|
|
82
86
|
name: r.name,
|
|
83
87
|
success: !0,
|
|
84
|
-
value:
|
|
88
|
+
value: i
|
|
85
89
|
};
|
|
86
90
|
} catch (n) {
|
|
87
|
-
|
|
88
|
-
const
|
|
91
|
+
a?.(n, r);
|
|
92
|
+
const i = n instanceof Error ? n.message : String(n);
|
|
89
93
|
return {
|
|
90
94
|
callId: r.id,
|
|
91
95
|
name: r.name,
|
|
92
96
|
success: !1,
|
|
93
|
-
error:
|
|
97
|
+
error: i
|
|
94
98
|
};
|
|
95
99
|
}
|
|
96
100
|
}
|
|
97
101
|
return {
|
|
98
|
-
|
|
99
|
-
return u(r)
|
|
100
|
-
|
|
101
|
-
async executeAll(r) {
|
|
102
|
-
return await Promise.all(
|
|
103
|
-
r.map((c) => u(c))
|
|
102
|
+
execute(r) {
|
|
103
|
+
return I(r) ? u(r) : Promise.all(
|
|
104
|
+
r.map((n) => u(n))
|
|
104
105
|
);
|
|
105
106
|
},
|
|
106
107
|
hasTool(r) {
|
|
@@ -108,17 +109,17 @@ function H(e) {
|
|
|
108
109
|
}
|
|
109
110
|
};
|
|
110
111
|
}
|
|
111
|
-
function
|
|
112
|
+
function H(e) {
|
|
112
113
|
const {
|
|
113
114
|
vectorStore: t,
|
|
114
|
-
name:
|
|
115
|
-
description:
|
|
116
|
-
defaultLimit:
|
|
117
|
-
maxLimit:
|
|
115
|
+
name: s,
|
|
116
|
+
description: a,
|
|
117
|
+
defaultLimit: c = L,
|
|
118
|
+
maxLimit: o = _,
|
|
118
119
|
scoreThreshold: u,
|
|
119
|
-
formatResult: r =
|
|
120
|
+
formatResult: r = M,
|
|
120
121
|
extendParameters: n = {},
|
|
121
|
-
buildFilter:
|
|
122
|
+
buildFilter: i
|
|
122
123
|
} = e, f = {
|
|
123
124
|
type: "object",
|
|
124
125
|
properties: {
|
|
@@ -128,17 +129,17 @@ function N(e) {
|
|
|
128
129
|
},
|
|
129
130
|
limit: {
|
|
130
131
|
type: "integer",
|
|
131
|
-
description: `Maximum number of results to return (default: ${
|
|
132
|
+
description: `Maximum number of results to return (default: ${c}, max: ${o})`,
|
|
132
133
|
minimum: 1,
|
|
133
|
-
maximum:
|
|
134
|
-
default:
|
|
134
|
+
maximum: o,
|
|
135
|
+
default: c
|
|
135
136
|
},
|
|
136
137
|
...n
|
|
137
138
|
},
|
|
138
139
|
required: ["query"]
|
|
139
140
|
}, m = {
|
|
140
|
-
name:
|
|
141
|
-
description:
|
|
141
|
+
name: s,
|
|
142
|
+
description: a,
|
|
142
143
|
parameters: f
|
|
143
144
|
};
|
|
144
145
|
async function d(h) {
|
|
@@ -146,73 +147,62 @@ function N(e) {
|
|
|
146
147
|
if (typeof y != "string" || y.length === 0)
|
|
147
148
|
return [];
|
|
148
149
|
const p = h.limit;
|
|
149
|
-
let E =
|
|
150
|
-
typeof p == "number" && Number.isInteger(p) && (E = Math.min(Math.max(1, p),
|
|
151
|
-
const
|
|
152
|
-
let
|
|
153
|
-
return u !== void 0 && (
|
|
150
|
+
let E = c;
|
|
151
|
+
typeof p == "number" && Number.isInteger(p) && (E = Math.min(Math.max(1, p), o));
|
|
152
|
+
const w = i?.(h), v = w !== void 0 ? { limit: E, filter: w } : { limit: E }, g = await t.search(y, v);
|
|
153
|
+
let T = g;
|
|
154
|
+
return u !== void 0 && (T = g.filter((x) => x.score >= u)), T.map(r);
|
|
154
155
|
}
|
|
155
156
|
return { schema: m, handler: d };
|
|
156
157
|
}
|
|
157
|
-
function
|
|
158
|
-
return {
|
|
159
|
-
content: e.content,
|
|
160
|
-
score: e.score,
|
|
161
|
-
metadata: e.metadata
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
function V(e) {
|
|
158
|
+
function N(e) {
|
|
165
159
|
const {
|
|
166
160
|
form: t,
|
|
167
|
-
confirmFn:
|
|
168
|
-
message:
|
|
169
|
-
excludePages:
|
|
170
|
-
onlyFromPages:
|
|
161
|
+
confirmFn: s,
|
|
162
|
+
message: a = D,
|
|
163
|
+
excludePages: c = [],
|
|
164
|
+
onlyFromPages: o
|
|
171
165
|
} = e;
|
|
172
166
|
return async function(r, n) {
|
|
173
|
-
return
|
|
167
|
+
return k(r, n, c, o) || !t.isDirty() ? !0 : Promise.resolve(s(a));
|
|
174
168
|
};
|
|
175
169
|
}
|
|
176
|
-
function
|
|
177
|
-
return !!(o.includes(e) || s !== void 0 && !s.includes(t));
|
|
178
|
-
}
|
|
179
|
-
function Y(e) {
|
|
170
|
+
function V(e) {
|
|
180
171
|
const {
|
|
181
172
|
database: t,
|
|
182
|
-
storeName:
|
|
183
|
-
autoprune:
|
|
184
|
-
onSaveError:
|
|
185
|
-
} = e,
|
|
186
|
-
s !== void 0 && s > 0 && u(s);
|
|
173
|
+
storeName: s,
|
|
174
|
+
autoprune: a,
|
|
175
|
+
onSaveError: c
|
|
176
|
+
} = e, o = t.store(s);
|
|
187
177
|
async function u(r) {
|
|
188
|
-
const
|
|
178
|
+
const i = Date.now() - r, f = await o.all();
|
|
189
179
|
let m = 0;
|
|
190
180
|
for (const d of f)
|
|
191
|
-
d.updatedAt <
|
|
181
|
+
d.updatedAt < i && (await o.remove(d.id), m++);
|
|
192
182
|
return m;
|
|
193
183
|
}
|
|
194
|
-
return {
|
|
184
|
+
return a !== void 0 && a > 0 && u(a), {
|
|
195
185
|
async save(r, n) {
|
|
196
186
|
try {
|
|
197
|
-
const
|
|
187
|
+
const i = {
|
|
198
188
|
id: r,
|
|
199
189
|
messages: [...n.getMessages()],
|
|
200
190
|
metadata: n.getMetadata(),
|
|
201
191
|
updatedAt: Date.now()
|
|
202
192
|
};
|
|
203
|
-
await
|
|
204
|
-
} catch (
|
|
205
|
-
throw
|
|
193
|
+
await o.set(i, r);
|
|
194
|
+
} catch (i) {
|
|
195
|
+
throw c?.(i, r), i;
|
|
206
196
|
}
|
|
207
197
|
},
|
|
208
198
|
async load(r) {
|
|
209
|
-
return
|
|
199
|
+
return o.get(r);
|
|
210
200
|
},
|
|
211
201
|
async delete(r) {
|
|
212
|
-
await
|
|
202
|
+
await o.remove(r);
|
|
213
203
|
},
|
|
214
204
|
async list() {
|
|
215
|
-
return (await
|
|
205
|
+
return (await o.all()).map((n) => n.id);
|
|
216
206
|
},
|
|
217
207
|
async prune(r) {
|
|
218
208
|
return u(r);
|
|
@@ -220,27 +210,28 @@ function Y(e) {
|
|
|
220
210
|
};
|
|
221
211
|
}
|
|
222
212
|
export {
|
|
223
|
-
|
|
224
|
-
A as
|
|
225
|
-
|
|
226
|
-
L as
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
$ as
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
213
|
+
R as BRIDGE_DEFAULT_TIMEOUT,
|
|
214
|
+
A as EcosystemError,
|
|
215
|
+
D as FORM_DIRTY_DEFAULT_MESSAGE,
|
|
216
|
+
L as RETRIEVAL_DEFAULT_LIMIT,
|
|
217
|
+
_ as RETRIEVAL_MAX_LIMIT,
|
|
218
|
+
O as chain,
|
|
219
|
+
$ as computeContentHash,
|
|
220
|
+
N as createFormDirtyGuard,
|
|
221
|
+
H as createRetrievalTool,
|
|
222
|
+
V as createSessionPersistence,
|
|
223
|
+
j as createToolCallBridge,
|
|
224
|
+
l as err,
|
|
225
|
+
M as formatScoredResult,
|
|
226
|
+
b as isEcosystemError,
|
|
227
|
+
P as isErr,
|
|
228
|
+
F as isOk,
|
|
229
|
+
I as isToolCall,
|
|
240
230
|
B as map,
|
|
241
231
|
G as mapErr,
|
|
242
232
|
S as ok,
|
|
243
|
-
|
|
233
|
+
k as shouldSkipFormGuard,
|
|
234
|
+
q as unwrap,
|
|
244
235
|
U as unwrapOrThrow
|
|
245
236
|
};
|
|
246
237
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/errors.ts","../src/helpers.ts","../src/constants.ts","../src/bridges/tool-call.ts","../src/bridges/retrieval-tool.ts","../src/bridges/form-dirty-guard.ts","../src/bridges/session-persistence.ts"],"sourcesContent":["/**\r\n * @mikesaintsg/core\r\n *\r\n * Error utilities and re-exports.\r\n */\r\n\r\n// ============================================================================\r\n// Base Ecosystem Error\r\n// ============================================================================\r\n\r\nimport { CoreErrorCode } from './types'\r\n\r\n/**\r\n * Base error class for all ecosystem errors.\r\n * All package-specific errors should extend this class.\r\n */\r\nexport abstract class EcosystemError extends Error {\r\n\tabstract readonly code: string\r\n\toverride readonly cause: Error | undefined\r\n\r\n\tconstructor(message: string, cause?: Error) {\r\n\t\tsuper(message)\r\n\t\tthis.name = this.constructor.name\r\n\t\tthis.cause = cause\r\n\t}\r\n}\r\n\r\n/**\r\n * Type guard for ecosystem errors.\r\n *\r\n * @param error - The value to check\r\n * @returns True if the error is an EcosystemError\r\n *\r\n * @example\r\n * ```ts\r\n * try {\r\n * await someOperation()\r\n * } catch (error) {\r\n * if (isEcosystemError(error)) {\r\n * console.log('Code:', error.code)\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function isEcosystemError(error: unknown): error is EcosystemError {\r\n\treturn error instanceof EcosystemError\r\n}\r\n\r\n// ============================================================================\r\n// Core Error Class\r\n// ============================================================================\r\n\r\n/**\r\n * Core package error.\r\n *\r\n * @example\r\n * ```ts\r\n * throw new CoreError('ADAPTER_ERROR', 'Failed to connect to OpenAI')\r\n * ```\r\n */\r\nexport class CoreError extends Error {\r\n\treadonly code: CoreErrorCode\r\n\toverride readonly cause: Error | undefined\r\n\r\n\tconstructor(code: CoreErrorCode, message: string, cause?: Error) {\r\n\t\tsuper(message)\r\n\t\tthis.name = 'CoreError'\r\n\t\tthis.code = code\r\n\t\tthis.cause = cause\r\n\t}\r\n}\r\n\r\n/**\r\n * Type guard to check if an error is a CoreError.\r\n *\r\n * @param error - The value to check\r\n * @returns True if the error is a CoreError\r\n *\r\n * @example\r\n * ```ts\r\n * try {\r\n * await adapter.embed(['text'])\r\n * } catch (error) {\r\n * if (isCoreError(error)) {\r\n * console.log('Code:', error.code)\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function isCoreError(error: unknown): error is CoreError {\r\n\treturn error instanceof CoreError\r\n}\r\n","/**\r\n * @mikesaintsg/core\r\n *\r\n * Helper functions and type guards.\r\n */\r\n\r\nimport type { Ok, Err, Result, ContentHash } from './types.js'\r\n\r\n// ============================================================================\r\n// Result Pattern Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Create a success result.\r\n *\r\n * @param value - The success value\r\n * @returns An Ok result containing the value\r\n *\r\n * @example\r\n * ```ts\r\n * const result = ok(42)\r\n * // result.ok === true\r\n * // result.value === 42\r\n * ```\r\n */\r\nexport function ok<T>(value: T): Ok<T> {\r\n\treturn { ok: true, value }\r\n}\r\n\r\n/**\r\n * Create a failure result.\r\n *\r\n * @param error - The error value\r\n * @returns An Err result containing the error\r\n *\r\n * @example\r\n * ```ts\r\n * const result = err('NOT_FOUND')\r\n * // result.ok === false\r\n * // result.error === 'NOT_FOUND'\r\n * ```\r\n */\r\nexport function err<E>(error: E): Err<E> {\r\n\treturn { ok: false, error }\r\n}\r\n\r\n/**\r\n * Check if a result is a success.\r\n *\r\n * @param result - The result to check\r\n * @returns True if the result is Ok, false otherwise\r\n *\r\n * @example\r\n * ```ts\r\n * const result: Result<number, string> = ok(42)\r\n * if (isOk(result)) {\r\n * console.log(result.value) // TypeScript knows result is Ok<number>\r\n * }\r\n * ```\r\n */\r\nexport function isOk<T, E>(result: Result<T, E>): result is Ok<T> {\r\n\treturn result.ok === true\r\n}\r\n\r\n/**\r\n * Check if a result is a failure.\r\n *\r\n * @param result - The result to check\r\n * @returns True if the result is Err, false otherwise\r\n *\r\n * @example\r\n * ```ts\r\n * const result: Result<number, string> = err('NOT_FOUND')\r\n * if (isErr(result)) {\r\n * console.log(result.error) // TypeScript knows result is Err<string>\r\n * }\r\n * ```\r\n */\r\nexport function isErr<T, E>(result: Result<T, E>): result is Err<E> {\r\n\treturn !result.ok\r\n}\r\n\r\n/**\r\n * Unwrap a result, returning the value or a default.\r\n *\r\n * @param result - The result to unwrap\r\n * @param defaultValue - Value to return if result is an error\r\n * @returns The success value or the default value\r\n *\r\n * @example\r\n * ```ts\r\n * const value = unwrap(ok(42), 0) // 42\r\n * const fallback = unwrap(err('oops'), 0) // 0\r\n * ```\r\n */\r\nexport function unwrap<T, E>(result: Result<T, E>, defaultValue: T): T {\r\n\treturn result.ok ? result.value : defaultValue\r\n}\r\n\r\n/**\r\n * Unwrap a result, throwing if it's an error.\r\n *\r\n * @param result - The result to unwrap\r\n * @returns The success value\r\n * @throws The error if result is Err\r\n *\r\n * @example\r\n * ```ts\r\n * const value = unwrapOrThrow(ok(42)) // 42\r\n * unwrapOrThrow(err(new Error('oops'))) // throws Error('oops')\r\n * ```\r\n */\r\nexport function unwrapOrThrow<T, E>(result: Result<T, E>): T {\r\n\tif (result.ok) {\r\n\t\treturn result.value\r\n\t}\r\n\tif (result.error instanceof Error) {\r\n\t\tthrow result.error\r\n\t}\r\n\tthrow new Error(String(result.error))\r\n}\r\n\r\n/**\r\n * Map a function over a success value.\r\n *\r\n * @param result - The result to map over\r\n * @param fn - Function to apply to the success value\r\n * @returns A new result with the mapped value, or the original error\r\n *\r\n * @example\r\n * ```ts\r\n * const doubled = map(ok(5), x => x * 2) // ok(10)\r\n * const failed = map(err('oops'), x => x * 2) // err('oops')\r\n * ```\r\n */\r\nexport function map<T, U, E>(\r\n\tresult: Result<T, E>,\r\n\tfn: (value: T) => U,\r\n): Result<U, E> {\r\n\treturn result.ok ? ok(fn(result.value)) : result\r\n}\r\n\r\n/**\r\n * Map a function over an error value.\r\n *\r\n * @param result - The result to map over\r\n * @param fn - Function to apply to the error value\r\n * @returns A new result with the mapped error, or the original value\r\n *\r\n * @example\r\n * ```ts\r\n * const wrapped = mapErr(err('oops'), e => new Error(e)) // err(Error('oops'))\r\n * const unchanged = mapErr(ok(42), e => new Error(e)) // ok(42)\r\n * ```\r\n */\r\nexport function mapErr<T, E, F>(\r\n\tresult: Result<T, E>,\r\n\tfn: (error: E) => F,\r\n): Result<T, F> {\r\n\treturn result.ok ? result : err(fn(result.error))\r\n}\r\n\r\n/**\r\n * Chain results (flatMap). Apply a function that returns a Result to a success value.\r\n *\r\n * @param result - The result to chain\r\n * @param fn - Function returning a new Result\r\n * @returns The result of applying fn, or the original error\r\n *\r\n * @example\r\n * ```ts\r\n * const parsed = chain(ok('42'), s => {\r\n * const n = parseInt(s, 10)\r\n * return isNaN(n) ? err('PARSE_ERROR') : ok(n)\r\n * })\r\n * // parsed = ok(42)\r\n * ```\r\n */\r\nexport function chain<T, U, E>(\r\n\tresult: Result<T, E>,\r\n\tfn: (value: T) => Result<U, E>,\r\n): Result<U, E> {\r\n\treturn result.ok ? fn(result.value) : result\r\n}\r\n\r\n// ============================================================================\r\n// Content Hashing Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Compute a SHA-256 content hash for text.\r\n *\r\n * @param text - The text to hash\r\n * @returns A hex string content hash\r\n *\r\n * @example\r\n * ```ts\r\n * const hash = await computeContentHash('Hello, world!')\r\n * // hash = 'a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e'\r\n * ```\r\n */\r\nexport async function computeContentHash(text: string): Promise<ContentHash> {\r\n\tconst encoder = new TextEncoder()\r\n\tconst data = encoder.encode(text)\r\n\tconst hashBuffer = await crypto.subtle.digest('SHA-256', data)\r\n\tconst hashArray = Array.from(new Uint8Array(hashBuffer))\r\n\treturn hashArray.map(b => b.toString(16).padStart(2, '0')).join('')\r\n}\r\n","/**\r\n * @mikesaintsg/core\r\n *\r\n * Shared constants for the core library.\r\n */\r\n\r\n// ============================================================================\r\n// Bridge Constants\r\n// ============================================================================\r\n\r\n/** Default timeout for bridge operations in milliseconds */\r\nexport const BRIDGE_DEFAULT_TIMEOUT = 30000\r\n\r\n/** Default retrieval limit for retrieval tool */\r\nexport const RETRIEVAL_DEFAULT_LIMIT = 10\r\n\r\n/** Maximum retrieval limit for retrieval tool */\r\nexport const RETRIEVAL_MAX_LIMIT = 100\r\n\r\n/** Default form dirty guard message */\r\nexport const FORM_DIRTY_DEFAULT_MESSAGE = 'You have unsaved changes. Are you sure you want to leave?'\r\n","/**\r\n * @mikesaintsg/core\r\n *\r\n * Tool call bridge that connects inference tool calls to contextprotocol tool registry.\r\n */\r\n\r\nimport type {\r\n\tToolCall,\r\n\tToolResult,\r\n\tToolCallBridgeOptions,\r\n\tToolCallBridgeInterface,\r\n} from '../types.js'\r\nimport { BRIDGE_DEFAULT_TIMEOUT } from '../constants.js'\r\n\r\n/**\r\n * Create a tool call bridge.\r\n *\r\n * @param options - Bridge configuration options\r\n * @returns A tool call bridge instance\r\n *\r\n * @example\r\n * ```ts\r\n * import { createToolRegistry } from '@mikesaintsg/contextprotocol'\r\n * import { createToolCallBridge } from '@mikesaintsg/core'\r\n *\r\n * const registry = createToolRegistry()\r\n * registry.register(weatherTool)\r\n *\r\n * const bridge = createToolCallBridge({\r\n * registry,\r\n * timeout: 30000,\r\n * onError: (error, toolCall) => console.error(`Tool ${toolCall.name} failed:`, error),\r\n * })\r\n *\r\n * // Execute tool calls from LLM response\r\n * const results = await bridge.executeAll(response.toolCalls)\r\n * ```\r\n */\r\nexport function createToolCallBridge(\r\n\toptions: ToolCallBridgeOptions,\r\n): ToolCallBridgeInterface {\r\n\tconst {\r\n\t\tregistry,\r\n\t\ttimeout = BRIDGE_DEFAULT_TIMEOUT,\r\n\t\tonError,\r\n\t\tonBeforeExecute,\r\n\t\tonAfterExecute,\r\n\t} = options\r\n\r\n\t/**\r\n\t * Execute a single tool call with timeout.\r\n\t */\r\n\tasync function executeWithTimeout(\r\n\t\ttoolCall: ToolCall,\r\n\t): Promise<ToolResult> {\r\n\t\t// Check if tool exists\r\n\t\tif (!registry.has(toolCall.name)) {\r\n\t\t\tconst result: ToolResult = {\r\n\t\t\t\tcallId: toolCall.id,\r\n\t\t\t\tname: toolCall.name,\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: `Tool not found: ${toolCall.name}`,\r\n\t\t\t}\r\n\t\t\treturn result\r\n\t\t}\r\n\r\n\t\t// Call lifecycle hook\r\n\t\tonBeforeExecute?.(toolCall)\r\n\r\n\t\ttry {\r\n\t\t\t// Create timeout promise\r\n\t\t\tconst timeoutPromise = new Promise<never>((_, reject) => {\r\n\t\t\t\tsetTimeout(() => {\r\n\t\t\t\t\treject(new Error(`Tool execution timed out after ${timeout}ms`))\r\n\t\t\t\t}, timeout)\r\n\t\t\t})\r\n\r\n\t\t\t// Execute tool with timeout\r\n\t\t\tconst value = await Promise.race([\r\n\t\t\t\tregistry.execute(toolCall.name, toolCall.arguments),\r\n\t\t\t\ttimeoutPromise,\r\n\t\t\t])\r\n\r\n\t\t\t// Call lifecycle hook\r\n\t\t\tonAfterExecute?.(toolCall, value)\r\n\r\n\t\t\treturn {\r\n\t\t\t\tcallId: toolCall.id,\r\n\t\t\t\tname: toolCall.name,\r\n\t\t\t\tsuccess: true,\r\n\t\t\t\tvalue,\r\n\t\t\t}\r\n\t\t} catch (error) {\r\n\t\t\t// Call error hook\r\n\t\t\tonError?.(error, toolCall)\r\n\r\n\t\t\tconst errorMessage = error instanceof Error\r\n\t\t\t\t? error.message\r\n\t\t\t\t: String(error)\r\n\r\n\t\t\treturn {\r\n\t\t\t\tcallId: toolCall.id,\r\n\t\t\t\tname: toolCall.name,\r\n\t\t\t\tsuccess: false,\r\n\t\t\t\terror: errorMessage,\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\treturn {\r\n\t\tasync execute(toolCall: ToolCall): Promise<ToolResult> {\r\n\t\t\treturn executeWithTimeout(toolCall)\r\n\t\t},\r\n\r\n\t\tasync executeAll(toolCalls: readonly ToolCall[]): Promise<readonly ToolResult[]> {\r\n\t\t\t// Execute all tool calls in parallel\r\n\t\t\tconst results = await Promise.all(\r\n\t\t\t\ttoolCalls.map(toolCall => executeWithTimeout(toolCall)),\r\n\t\t\t)\r\n\t\t\treturn results\r\n\t\t},\r\n\r\n\t\thasTool(name: string): boolean {\r\n\t\t\treturn registry.has(name)\r\n\t\t},\r\n\t}\r\n}\r\n","/**\r\n * @mikesaintsg/core\r\n *\r\n * Retrieval tool factory that connects vectorstore to contextprotocol.\r\n */\r\n\r\nimport type {\r\n\tRetrievalToolOptions,\r\n\tRetrievalToolCreated,\r\n\tToolSchema,\r\n\tJSONSchema7,\r\n\tScoredResult,\r\n} from '../types.js'\r\nimport {\r\n\tRETRIEVAL_DEFAULT_LIMIT,\r\n\tRETRIEVAL_MAX_LIMIT,\r\n} from '../constants.js'\r\n\r\n/**\r\n * Create a retrieval tool for use with contextprotocol tool registry.\r\n *\r\n * @param options - Retrieval tool configuration options\r\n * @returns A tool schema and handler for registration\r\n *\r\n * @example\r\n * ```ts\r\n * import { createVectorStore } from '@mikesaintsg/vectorstore'\r\n * import { createToolRegistry } from '@mikesaintsg/contextprotocol'\r\n * import { createRetrievalTool } from '@mikesaintsg/core'\r\n *\r\n * const vectorStore = createVectorStore({ ... })\r\n * const registry = createToolRegistry()\r\n *\r\n * const { schema, handler } = createRetrievalTool({\r\n * vectorStore,\r\n * name: 'search_docs',\r\n * description: 'Search documentation for relevant information',\r\n * defaultLimit: 5,\r\n * scoreThreshold: 0.7,\r\n * })\r\n *\r\n * registry.register({ ...schema, execute: handler })\r\n * ```\r\n */\r\nexport function createRetrievalTool<TMetadata = unknown>(\r\n\toptions: RetrievalToolOptions<TMetadata>,\r\n): RetrievalToolCreated {\r\n\tconst {\r\n\t\tvectorStore,\r\n\t\tname,\r\n\t\tdescription,\r\n\t\tdefaultLimit = RETRIEVAL_DEFAULT_LIMIT,\r\n\t\tmaxLimit = RETRIEVAL_MAX_LIMIT,\r\n\t\tscoreThreshold,\r\n\t\tformatResult = defaultFormatResult,\r\n\t\textendParameters = {},\r\n\t\tbuildFilter,\r\n\t} = options\r\n\r\n\t// Build tool schema parameters\r\n\tconst parameters: JSONSchema7 = {\r\n\t\ttype: 'object',\r\n\t\tproperties: {\r\n\t\t\tquery: {\r\n\t\t\t\ttype: 'string',\r\n\t\t\t\tdescription: 'The search query to find relevant documents',\r\n\t\t\t},\r\n\t\t\tlimit: {\r\n\t\t\t\ttype: 'integer',\r\n\t\t\t\tdescription: `Maximum number of results to return (default: ${defaultLimit}, max: ${maxLimit})`,\r\n\t\t\t\tminimum: 1,\r\n\t\t\t\tmaximum: maxLimit,\r\n\t\t\t\tdefault: defaultLimit,\r\n\t\t\t},\r\n\t\t\t...extendParameters,\r\n\t\t},\r\n\t\trequired: ['query'],\r\n\t}\r\n\r\n\tconst schema: ToolSchema = {\r\n\t\tname,\r\n\t\tdescription,\r\n\t\tparameters,\r\n\t}\r\n\r\n\tasync function handler(\r\n\t\targs: Readonly<Record<string, unknown>>,\r\n\t): Promise<readonly unknown[]> {\r\n\t\tconst query = args.query\r\n\t\tif (typeof query !== 'string' || query.length === 0) {\r\n\t\t\treturn []\r\n\t\t}\r\n\r\n\t\tconst requestedLimit = args.limit\r\n\t\tlet limit = defaultLimit\r\n\t\tif (typeof requestedLimit === 'number' && Number.isInteger(requestedLimit)) {\r\n\t\t\tlimit = Math.min(Math.max(1, requestedLimit), maxLimit)\r\n\t\t}\r\n\r\n\t\t// Build filter if provided\r\n\t\tconst filter = buildFilter?.(args)\r\n\r\n\t\t// Search vectorstore - only include filter if defined\r\n\t\tconst searchOptions = filter !== undefined\r\n\t\t\t? { limit, filter }\r\n\t\t\t: { limit }\r\n\t\tconst results = await vectorStore.search(query, searchOptions)\r\n\r\n\t\t// Filter by score threshold\r\n\t\tlet filteredResults = results\r\n\t\tif (scoreThreshold !== undefined) {\r\n\t\t\tfilteredResults = results.filter(r => r.score >= scoreThreshold)\r\n\t\t}\r\n\r\n\t\t// Format results\r\n\t\treturn filteredResults.map(formatResult)\r\n\t}\r\n\r\n\treturn { schema, handler }\r\n}\r\n\r\n/**\r\n * Default result formatter - returns content and metadata.\r\n */\r\nfunction defaultFormatResult(result: ScoredResult): unknown {\r\n\treturn {\r\n\t\tcontent: result.content,\r\n\t\tscore: result.score,\r\n\t\tmetadata: result.metadata,\r\n\t}\r\n}\r\n","/**\r\n * @mikesaintsg/core\r\n *\r\n * Form dirty guard that prevents navigation when form has unsaved changes.\r\n */\r\n\r\nimport type {\r\n\tFormDirtyGuardOptions,\r\n\tNavigationGuard,\r\n} from '../types.js'\r\nimport { FORM_DIRTY_DEFAULT_MESSAGE } from '../constants.js'\r\n\r\n/**\r\n * Create a navigation guard that prevents leaving when form is dirty.\r\n *\r\n * @param options - Form dirty guard configuration options\r\n * @returns A navigation guard function\r\n *\r\n * @example\r\n * ```ts\r\n * import { createForm } from '@mikesaintsg/form'\r\n * import { createFormDirtyGuard } from '@mikesaintsg/core'\r\n *\r\n * const form = createForm({ ... })\r\n *\r\n * const guard = createFormDirtyGuard({\r\n * form,\r\n * confirmFn: (message) => window.confirm(message),\r\n * message: 'You have unsaved changes. Continue?',\r\n * excludePages: ['settings'],\r\n * })\r\n *\r\n * // Use with router\r\n * router.beforeNavigate(guard)\r\n * ```\r\n */\r\nexport function createFormDirtyGuard<TFormData = unknown, TPage extends string = string>(\r\n\toptions: FormDirtyGuardOptions<TFormData, TPage>,\r\n): NavigationGuard<TPage> {\r\n\tconst {\r\n\t\tform,\r\n\t\tconfirmFn,\r\n\t\tmessage = FORM_DIRTY_DEFAULT_MESSAGE,\r\n\t\texcludePages = [],\r\n\t\tonlyFromPages,\r\n\t} = options\r\n\r\n\treturn async function guard(to: TPage, from: TPage): Promise<boolean> {\r\n\t\t// Check if we should skip guard for this navigation\r\n\t\tif (shouldSkipGuard(to, from, excludePages, onlyFromPages)) {\r\n\t\t\treturn true\r\n\t\t}\r\n\r\n\t\t// If form is not dirty, allow navigation\r\n\t\tif (!form.isDirty()) {\r\n\t\t\treturn true\r\n\t\t}\r\n\r\n\t\t// Form is dirty, ask for confirmation\r\n\t\tconst confirmed = await Promise.resolve(confirmFn(message))\r\n\t\treturn confirmed\r\n\t}\r\n}\r\n\r\n/**\r\n * Determine if guard should be skipped for this navigation.\r\n */\r\nfunction shouldSkipGuard<TPage extends string>(\r\n\tto: TPage,\r\n\tfrom: TPage,\r\n\texcludePages: readonly TPage[],\r\n\tonlyFromPages: readonly TPage[] | undefined,\r\n): boolean {\r\n\t// Skip if navigating to excluded page\r\n\tif (excludePages.includes(to)) {\r\n\t\treturn true\r\n\t}\r\n\r\n\t// Skip if from page is not in onlyFromPages (if specified)\r\n\tif (onlyFromPages !== undefined && !onlyFromPages.includes(from)) {\r\n\t\treturn true\r\n\t}\r\n\r\n\treturn false\r\n}\r\n","/**\r\n * @mikesaintsg/core\r\n *\r\n * Session persistence bridge that connects inference sessions to IndexedDB storage.\r\n */\r\n\r\nimport type {\r\n\tSessionPersistenceOptions,\r\n\tSessionPersistenceInterface,\r\n\tSerializableSession,\r\n\tSerializedSession,\r\n} from '../types.js'\r\n\r\n/**\r\n * Create a session persistence adapter for storing inference sessions.\r\n *\r\n * @param options - Session persistence configuration options\r\n * @returns A session persistence instance\r\n *\r\n * @example\r\n * ```ts\r\n * import { createDatabase } from '@mikesaintsg/indexeddb'\r\n * import { createSessionPersistence } from '@mikesaintsg/core'\r\n *\r\n * const db = await createDatabase({ name: 'sessions' })\r\n * const persistence = createSessionPersistence({\r\n * database: db,\r\n * storeName: 'chat_sessions',\r\n * autoprune: 7 * 24 * 60 * 60 * 1000, // 7 days\r\n * })\r\n *\r\n * // Save session\r\n * await persistence.save('session-1', session)\r\n *\r\n * // Load session\r\n * const savedSession = await persistence.load('session-1')\r\n * ```\r\n */\r\nexport function createSessionPersistence(\r\n\toptions: SessionPersistenceOptions,\r\n): SessionPersistenceInterface {\r\n\tconst {\r\n\t\tdatabase,\r\n\t\tstoreName,\r\n\t\tautoprune,\r\n\t\tonSaveError,\r\n\t} = options\r\n\r\n\tconst store = database.store<SerializedSession>(storeName)\r\n\r\n\t// Auto-prune on creation if configured\r\n\tif (autoprune !== undefined && autoprune > 0) {\r\n\t\tvoid pruneOldSessions(autoprune)\r\n\t}\r\n\r\n\t/**\r\n\t * Prune sessions older than maxAgeMs.\r\n\t */\r\n\tasync function pruneOldSessions(maxAgeMs: number): Promise<number> {\r\n\t\tconst now = Date.now()\r\n\t\tconst cutoff = now - maxAgeMs\r\n\r\n\t\tconst allSessions = await store.all()\r\n\t\tlet prunedCount = 0\r\n\r\n\t\tfor (const session of allSessions) {\r\n\t\t\tif (session.updatedAt < cutoff) {\r\n\t\t\t\tawait store.remove(session.id)\r\n\t\t\t\tprunedCount++\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn prunedCount\r\n\t}\r\n\r\n\treturn {\r\n\t\tasync save(id: string, session: SerializableSession): Promise<void> {\r\n\t\t\ttry {\r\n\t\t\t\tconst serialized: SerializedSession = {\r\n\t\t\t\t\tid,\r\n\t\t\t\t\tmessages: [...session.getMessages()],\r\n\t\t\t\t\tmetadata: session.getMetadata(),\r\n\t\t\t\t\tupdatedAt: Date.now(),\r\n\t\t\t\t}\r\n\r\n\t\t\t\tawait store.set(serialized, id)\r\n\t\t\t} catch (error) {\r\n\t\t\t\tonSaveError?.(error, id)\r\n\t\t\t\tthrow error\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\tasync load(id: string): Promise<SerializedSession | undefined> {\r\n\t\t\treturn store.get(id)\r\n\t\t},\r\n\r\n\t\tasync delete(id: string): Promise<void> {\r\n\t\t\tawait store.remove(id)\r\n\t\t},\r\n\r\n\t\tasync list(): Promise<readonly string[]> {\r\n\t\t\tconst allSessions = await store.all()\r\n\t\t\treturn allSessions.map(s => s.id)\r\n\t\t},\r\n\r\n\t\tasync prune(maxAgeMs: number): Promise<number> {\r\n\t\t\treturn pruneOldSessions(maxAgeMs)\r\n\t\t},\r\n\t}\r\n}\r\n"],"names":["EcosystemError","message","cause","isEcosystemError","error","CoreError","code","isCoreError","ok","value","err","isOk","result","isErr","unwrap","defaultValue","unwrapOrThrow","map","fn","mapErr","chain","computeContentHash","text","data","hashBuffer","b","BRIDGE_DEFAULT_TIMEOUT","RETRIEVAL_DEFAULT_LIMIT","RETRIEVAL_MAX_LIMIT","FORM_DIRTY_DEFAULT_MESSAGE","createToolCallBridge","options","registry","timeout","onError","onBeforeExecute","onAfterExecute","executeWithTimeout","toolCall","timeoutPromise","_","reject","errorMessage","toolCalls","name","createRetrievalTool","vectorStore","description","defaultLimit","maxLimit","scoreThreshold","formatResult","defaultFormatResult","extendParameters","buildFilter","parameters","schema","handler","args","query","requestedLimit","limit","filter","searchOptions","results","filteredResults","r","createFormDirtyGuard","form","confirmFn","excludePages","onlyFromPages","to","from","shouldSkipGuard","createSessionPersistence","database","storeName","autoprune","onSaveError","store","pruneOldSessions","maxAgeMs","cutoff","allSessions","prunedCount","session","id","serialized","s"],"mappings":"AAgBO,MAAeA,UAAuB,MAAM;AAAA,EAEhC;AAAA,EAElB,YAAYC,GAAiBC,GAAe;AAC3C,UAAMD,CAAO,GACb,KAAK,OAAO,KAAK,YAAY,MAC7B,KAAK,QAAQC;AAAA,EACd;AACD;AAmBO,SAASC,EAAiBC,GAAyC;AACzE,SAAOA,aAAiBJ;AACzB;AAcO,MAAMK,UAAkB,MAAM;AAAA,EAC3B;AAAA,EACS;AAAA,EAElB,YAAYC,GAAqBL,GAAiBC,GAAe;AAChE,UAAMD,CAAO,GACb,KAAK,OAAO,aACZ,KAAK,OAAOK,GACZ,KAAK,QAAQJ;AAAA,EACd;AACD;AAmBO,SAASK,EAAYH,GAAoC;AAC/D,SAAOA,aAAiBC;AACzB;AClEO,SAASG,EAAMC,GAAiB;AACtC,SAAO,EAAE,IAAI,IAAM,OAAAA,EAAA;AACpB;AAeO,SAASC,EAAON,GAAkB;AACxC,SAAO,EAAE,IAAI,IAAO,OAAAA,EAAA;AACrB;AAgBO,SAASO,EAAWC,GAAuC;AACjE,SAAOA,EAAO,OAAO;AACtB;AAgBO,SAASC,EAAYD,GAAwC;AACnE,SAAO,CAACA,EAAO;AAChB;AAeO,SAASE,EAAaF,GAAsBG,GAAoB;AACtE,SAAOH,EAAO,KAAKA,EAAO,QAAQG;AACnC;AAeO,SAASC,EAAoBJ,GAAyB;AAC5D,MAAIA,EAAO;AACV,WAAOA,EAAO;AAEf,QAAIA,EAAO,iBAAiB,QACrBA,EAAO,QAER,IAAI,MAAM,OAAOA,EAAO,KAAK,CAAC;AACrC;AAeO,SAASK,EACfL,GACAM,GACe;AACf,SAAON,EAAO,KAAKJ,EAAGU,EAAGN,EAAO,KAAK,CAAC,IAAIA;AAC3C;AAeO,SAASO,EACfP,GACAM,GACe;AACf,SAAON,EAAO,KAAKA,IAASF,EAAIQ,EAAGN,EAAO,KAAK,CAAC;AACjD;AAkBO,SAASQ,EACfR,GACAM,GACe;AACf,SAAON,EAAO,KAAKM,EAAGN,EAAO,KAAK,IAAIA;AACvC;AAkBA,eAAsBS,EAAmBC,GAAoC;AAE5E,QAAMC,IADU,IAAI,YAAA,EACC,OAAOD,CAAI,GAC1BE,IAAa,MAAM,OAAO,OAAO,OAAO,WAAWD,CAAI;AAE7D,SADkB,MAAM,KAAK,IAAI,WAAWC,CAAU,CAAC,EACtC,IAAI,CAAAC,MAAKA,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AACnE;ACpMO,MAAMC,IAAyB,KAGzBC,IAA0B,IAG1BC,IAAsB,KAGtBC,IAA6B;ACkBnC,SAASC,EACfC,GAC0B;AAC1B,QAAM;AAAA,IACL,UAAAC;AAAA,IACA,SAAAC,IAAUP;AAAA,IACV,SAAAQ;AAAA,IACA,iBAAAC;AAAA,IACA,gBAAAC;AAAA,EAAA,IACGL;AAKJ,iBAAeM,EACdC,GACsB;AAEtB,QAAI,CAACN,EAAS,IAAIM,EAAS,IAAI;AAO9B,aAN2B;AAAA,QAC1B,QAAQA,EAAS;AAAA,QACjB,MAAMA,EAAS;AAAA,QACf,SAAS;AAAA,QACT,OAAO,mBAAmBA,EAAS,IAAI;AAAA,MAAA;AAMzC,IAAAH,IAAkBG,CAAQ;AAE1B,QAAI;AAEH,YAAMC,IAAiB,IAAI,QAAe,CAACC,GAAGC,MAAW;AACxD,mBAAW,MAAM;AAChB,UAAAA,EAAO,IAAI,MAAM,kCAAkCR,CAAO,IAAI,CAAC;AAAA,QAChE,GAAGA,CAAO;AAAA,MACX,CAAC,GAGKxB,IAAQ,MAAM,QAAQ,KAAK;AAAA,QAChCuB,EAAS,QAAQM,EAAS,MAAMA,EAAS,SAAS;AAAA,QAClDC;AAAA,MAAA,CACA;AAGD,aAAAH,IAAiBE,GAAU7B,CAAK,GAEzB;AAAA,QACN,QAAQ6B,EAAS;AAAA,QACjB,MAAMA,EAAS;AAAA,QACf,SAAS;AAAA,QACT,OAAA7B;AAAA,MAAA;AAAA,IAEF,SAASL,GAAO;AAEf,MAAA8B,IAAU9B,GAAOkC,CAAQ;AAEzB,YAAMI,IAAetC,aAAiB,QACnCA,EAAM,UACN,OAAOA,CAAK;AAEf,aAAO;AAAA,QACN,QAAQkC,EAAS;AAAA,QACjB,MAAMA,EAAS;AAAA,QACf,SAAS;AAAA,QACT,OAAOI;AAAA,MAAA;AAAA,IAET;AAAA,EACD;AAEA,SAAO;AAAA,IACN,MAAM,QAAQJ,GAAyC;AACtD,aAAOD,EAAmBC,CAAQ;AAAA,IACnC;AAAA,IAEA,MAAM,WAAWK,GAAgE;AAKhF,aAHgB,MAAM,QAAQ;AAAA,QAC7BA,EAAU,IAAI,CAAAL,MAAYD,EAAmBC,CAAQ,CAAC;AAAA,MAAA;AAAA,IAGxD;AAAA,IAEA,QAAQM,GAAuB;AAC9B,aAAOZ,EAAS,IAAIY,CAAI;AAAA,IACzB;AAAA,EAAA;AAEF;AClFO,SAASC,EACfd,GACuB;AACvB,QAAM;AAAA,IACL,aAAAe;AAAA,IACA,MAAAF;AAAA,IACA,aAAAG;AAAA,IACA,cAAAC,IAAerB;AAAA,IACf,UAAAsB,IAAWrB;AAAA,IACX,gBAAAsB;AAAA,IACA,cAAAC,IAAeC;AAAA,IACf,kBAAAC,IAAmB,CAAA;AAAA,IACnB,aAAAC;AAAA,EAAA,IACGvB,GAGEwB,IAA0B;AAAA,IAC/B,MAAM;AAAA,IACN,YAAY;AAAA,MACX,OAAO;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MAAA;AAAA,MAEd,OAAO;AAAA,QACN,MAAM;AAAA,QACN,aAAa,iDAAiDP,CAAY,UAAUC,CAAQ;AAAA,QAC5F,SAAS;AAAA,QACT,SAASA;AAAA,QACT,SAASD;AAAA,MAAA;AAAA,MAEV,GAAGK;AAAA,IAAA;AAAA,IAEJ,UAAU,CAAC,OAAO;AAAA,EAAA,GAGbG,IAAqB;AAAA,IAC1B,MAAAZ;AAAA,IACA,aAAAG;AAAA,IACA,YAAAQ;AAAA,EAAA;AAGD,iBAAeE,EACdC,GAC8B;AAC9B,UAAMC,IAAQD,EAAK;AACnB,QAAI,OAAOC,KAAU,YAAYA,EAAM,WAAW;AACjD,aAAO,CAAA;AAGR,UAAMC,IAAiBF,EAAK;AAC5B,QAAIG,IAAQb;AACZ,IAAI,OAAOY,KAAmB,YAAY,OAAO,UAAUA,CAAc,MACxEC,IAAQ,KAAK,IAAI,KAAK,IAAI,GAAGD,CAAc,GAAGX,CAAQ;AAIvD,UAAMa,IAASR,IAAcI,CAAI,GAG3BK,IAAgBD,MAAW,SAC9B,EAAE,OAAAD,GAAO,QAAAC,EAAA,IACT,EAAE,OAAAD,EAAA,GACCG,IAAU,MAAMlB,EAAY,OAAOa,GAAOI,CAAa;AAG7D,QAAIE,IAAkBD;AACtB,WAAId,MAAmB,WACtBe,IAAkBD,EAAQ,OAAO,CAAAE,MAAKA,EAAE,SAAShB,CAAc,IAIzDe,EAAgB,IAAId,CAAY;AAAA,EACxC;AAEA,SAAO,EAAE,QAAAK,GAAQ,SAAAC,EAAA;AAClB;AAKA,SAASL,EAAoBxC,GAA+B;AAC3D,SAAO;AAAA,IACN,SAASA,EAAO;AAAA,IAChB,OAAOA,EAAO;AAAA,IACd,UAAUA,EAAO;AAAA,EAAA;AAEnB;AC9FO,SAASuD,EACfpC,GACyB;AACzB,QAAM;AAAA,IACL,MAAAqC;AAAA,IACA,WAAAC;AAAA,IACA,SAAApE,IAAU4B;AAAA,IACV,cAAAyC,IAAe,CAAA;AAAA,IACf,eAAAC;AAAA,EAAA,IACGxC;AAEJ,SAAO,eAAqByC,GAAWC,GAA+B;AAOrE,WALIC,EAAgBF,GAAIC,GAAMH,GAAcC,CAAa,KAKrD,CAACH,EAAK,YACF,KAIU,MAAM,QAAQ,QAAQC,EAAUpE,CAAO,CAAC;AAAA,EAE3D;AACD;AAKA,SAASyE,EACRF,GACAC,GACAH,GACAC,GACU;AAOV,SALI,GAAAD,EAAa,SAASE,CAAE,KAKxBD,MAAkB,UAAa,CAACA,EAAc,SAASE,CAAI;AAKhE;AC9CO,SAASE,EACf5C,GAC8B;AAC9B,QAAM;AAAA,IACL,UAAA6C;AAAA,IACA,WAAAC;AAAA,IACA,WAAAC;AAAA,IACA,aAAAC;AAAA,EAAA,IACGhD,GAEEiD,IAAQJ,EAAS,MAAyBC,CAAS;AAGzD,EAAIC,MAAc,UAAaA,IAAY,KACrCG,EAAiBH,CAAS;AAMhC,iBAAeG,EAAiBC,GAAmC;AAElE,UAAMC,IADM,KAAK,IAAA,IACID,GAEfE,IAAc,MAAMJ,EAAM,IAAA;AAChC,QAAIK,IAAc;AAElB,eAAWC,KAAWF;AACrB,MAAIE,EAAQ,YAAYH,MACvB,MAAMH,EAAM,OAAOM,EAAQ,EAAE,GAC7BD;AAIF,WAAOA;AAAA,EACR;AAEA,SAAO;AAAA,IACN,MAAM,KAAKE,GAAYD,GAA6C;AACnE,UAAI;AACH,cAAME,IAAgC;AAAA,UACrC,IAAAD;AAAA,UACA,UAAU,CAAC,GAAGD,EAAQ,aAAa;AAAA,UACnC,UAAUA,EAAQ,YAAA;AAAA,UAClB,WAAW,KAAK,IAAA;AAAA,QAAI;AAGrB,cAAMN,EAAM,IAAIQ,GAAYD,CAAE;AAAA,MAC/B,SAASnF,GAAO;AACf,cAAA2E,IAAc3E,GAAOmF,CAAE,GACjBnF;AAAA,MACP;AAAA,IACD;AAAA,IAEA,MAAM,KAAKmF,GAAoD;AAC9D,aAAOP,EAAM,IAAIO,CAAE;AAAA,IACpB;AAAA,IAEA,MAAM,OAAOA,GAA2B;AACvC,YAAMP,EAAM,OAAOO,CAAE;AAAA,IACtB;AAAA,IAEA,MAAM,OAAmC;AAExC,cADoB,MAAMP,EAAM,IAAA,GACb,IAAI,CAAAS,MAAKA,EAAE,EAAE;AAAA,IACjC;AAAA,IAEA,MAAM,MAAMP,GAAmC;AAC9C,aAAOD,EAAiBC,CAAQ;AAAA,IACjC;AAAA,EAAA;AAEF;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/errors.ts","../src/helpers.ts","../src/constants.ts","../src/factories.ts"],"sourcesContent":["/**\n * @mikesaintsg/core\n *\n * Base error class and utilities for the ecosystem.\n */\n// ============================================================================\n// Base Ecosystem Error\n// ============================================================================\n/**\n * Base error class for all ecosystem errors.\n * All package-specific errors should extend this class.\n *\n * @example\n * ```ts\n * class StorageError extends EcosystemError {\n * readonly code: StorageErrorCode\n *\n * constructor(code: StorageErrorCode, message: string, cause?: Error) {\n * super(message, cause)\n * this.code = code\n * }\n * }\n * ```\n */\nexport abstract class EcosystemError extends Error {\n\t/** Error code for programmatic handling */\n\tabstract readonly code: string\n\t/** Original error that caused this one */\n\toverride readonly cause: Error | undefined\n\n\tconstructor(message: string, cause?: Error) {\n\t\tsuper(message)\n\t\tthis.name = this.constructor.name\n\t\tthis.cause = cause\n\t}\n}\n/**\n * Type guard for ecosystem errors.\n *\n * @param error - The value to check\n * @returns True if the error is an EcosystemError\n *\n * @example\n * ```ts\n * try {\n * await someOperation()\n * } catch (error) {\n * if (isEcosystemError(error)) {\n * console.log('Code:', error.code)\n * }\n * }\n * ```\n */\nexport function isEcosystemError(error: unknown): error is EcosystemError {\n\treturn error instanceof EcosystemError\n}\n","/**\r\n * @mikesaintsg/core\r\n *\r\n * Helper functions and type guards.\r\n */\r\n\r\nimport type { Ok, Err, Result, ContentHash, ScoredResult } from './types.js'\r\n\r\n// ============================================================================\r\n// Result Pattern Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Create a success result.\r\n *\r\n * @param value - The success value\r\n * @returns An Ok result containing the value\r\n *\r\n * @example\r\n * ```ts\r\n * const result = ok(42)\r\n * // result.ok === true\r\n * // result.value === 42\r\n * ```\r\n */\r\nexport function ok<T>(value: T): Ok<T> {\r\n\treturn { ok: true, value }\r\n}\r\n\r\n/**\r\n * Create a failure result.\r\n *\r\n * @param error - The error value\r\n * @returns An Err result containing the error\r\n *\r\n * @example\r\n * ```ts\r\n * const result = err('NOT_FOUND')\r\n * // result.ok === false\r\n * // result.error === 'NOT_FOUND'\r\n * ```\r\n */\r\nexport function err<E>(error: E): Err<E> {\r\n\treturn { ok: false, error }\r\n}\r\n\r\n/**\r\n * Check if a result is a success.\r\n *\r\n * @param result - The result to check\r\n * @returns True if the result is Ok, false otherwise\r\n *\r\n * @example\r\n * ```ts\r\n * const result: Result<number, string> = ok(42)\r\n * if (isOk(result)) {\r\n * console.log(result.value) // TypeScript knows result is Ok<number>\r\n * }\r\n * ```\r\n */\r\nexport function isOk<T, E>(result: Result<T, E>): result is Ok<T> {\r\n\treturn result.ok === true\r\n}\r\n\r\n/**\r\n * Check if a result is a failure.\r\n *\r\n * @param result - The result to check\r\n * @returns True if the result is Err, false otherwise\r\n *\r\n * @example\r\n * ```ts\r\n * const result: Result<number, string> = err('NOT_FOUND')\r\n * if (isErr(result)) {\r\n * console.log(result.error) // TypeScript knows result is Err<string>\r\n * }\r\n * ```\r\n */\r\nexport function isErr<T, E>(result: Result<T, E>): result is Err<E> {\r\n\treturn !result.ok\r\n}\r\n\r\n/**\r\n * Unwrap a result, returning the value or a default.\r\n *\r\n * @param result - The result to unwrap\r\n * @param defaultValue - Value to return if result is an error\r\n * @returns The success value or the default value\r\n *\r\n * @example\r\n * ```ts\r\n * const value = unwrap(ok(42), 0) // 42\r\n * const fallback = unwrap(err('oops'), 0) // 0\r\n * ```\r\n */\r\nexport function unwrap<T, E>(result: Result<T, E>, defaultValue: T): T {\r\n\treturn result.ok ? result.value : defaultValue\r\n}\r\n\r\n/**\r\n * Unwrap a result, throwing if it's an error.\r\n *\r\n * @param result - The result to unwrap\r\n * @returns The success value\r\n * @throws The error if result is Err\r\n *\r\n * @example\r\n * ```ts\r\n * const value = unwrapOrThrow(ok(42)) // 42\r\n * unwrapOrThrow(err(new Error('oops'))) // throws Error('oops')\r\n * ```\r\n */\r\nexport function unwrapOrThrow<T, E>(result: Result<T, E>): T {\r\n\tif (result.ok) {\r\n\t\treturn result.value\r\n\t}\r\n\tif (result.error instanceof Error) {\r\n\t\tthrow result.error\r\n\t}\r\n\tthrow new Error(String(result.error))\r\n}\r\n\r\n/**\r\n * Map a function over a success value.\r\n *\r\n * @param result - The result to map over\r\n * @param fn - Function to apply to the success value\r\n * @returns A new result with the mapped value, or the original error\r\n *\r\n * @example\r\n * ```ts\r\n * const doubled = map(ok(5), x => x * 2) // ok(10)\r\n * const failed = map(err('oops'), x => x * 2) // err('oops')\r\n * ```\r\n */\r\nexport function map<T, U, E>(\r\n\tresult: Result<T, E>,\r\n\tfn: (value: T) => U,\r\n): Result<U, E> {\r\n\treturn result.ok ? ok(fn(result.value)) : result\r\n}\r\n\r\n/**\r\n * Map a function over an error value.\r\n *\r\n * @param result - The result to map over\r\n * @param fn - Function to apply to the error value\r\n * @returns A new result with the mapped error, or the original value\r\n *\r\n * @example\r\n * ```ts\r\n * const wrapped = mapErr(err('oops'), e => new Error(e)) // err(Error('oops'))\r\n * const unchanged = mapErr(ok(42), e => new Error(e)) // ok(42)\r\n * ```\r\n */\r\nexport function mapErr<T, E, F>(\r\n\tresult: Result<T, E>,\r\n\tfn: (error: E) => F,\r\n): Result<T, F> {\r\n\treturn result.ok ? result : err(fn(result.error))\r\n}\r\n\r\n/**\r\n * Chain results (flatMap). Apply a function that returns a Result to a success value.\r\n *\r\n * @param result - The result to chain\r\n * @param fn - Function returning a new Result\r\n * @returns The result of applying fn, or the original error\r\n *\r\n * @example\r\n * ```ts\r\n * const parsed = chain(ok('42'), s => {\r\n * const n = parseInt(s, 10)\r\n * return isNaN(n) ? err('PARSE_ERROR') : ok(n)\r\n * })\r\n * // parsed = ok(42)\r\n * ```\r\n */\r\nexport function chain<T, U, E>(\r\n\tresult: Result<T, E>,\r\n\tfn: (value: T) => Result<U, E>,\r\n): Result<U, E> {\r\n\treturn result.ok ? fn(result.value) : result\r\n}\r\n\r\n// ============================================================================\r\n// Content Hashing Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Compute a SHA-256 content hash for text.\r\n *\r\n * @param text - The text to hash\r\n * @returns A hex string content hash\r\n *\r\n * @example\r\n * ```ts\r\n * const hash = await computeContentHash('Hello, world!')\r\n * // hash = 'a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e'\r\n * ```\r\n */\r\nexport async function computeContentHash(text: string): Promise<ContentHash> {\r\n\tconst encoder = new TextEncoder()\r\n\tconst data = encoder.encode(text)\r\n\tconst hashBuffer = await crypto.subtle.digest('SHA-256', data)\r\n\tconst hashArray = Array.from(new Uint8Array(hashBuffer))\r\n\treturn hashArray.map(b => b.toString(16).padStart(2, '0')).join('')\r\n}\r\n\r\n// ============================================================================\r\n// Bridge Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Check if a value is a single ToolCall (not an array).\r\n *\r\n * @param value - Value to check\r\n * @returns True if the value is a single ToolCall\r\n */\r\nexport function isToolCall(value: unknown): value is { id: string; name: string; arguments: unknown } {\r\n\treturn (\r\n\t\ttypeof value === 'object' &&\r\n\t\tvalue !== null &&\r\n\t\t'id' in value &&\r\n\t\t'name' in value &&\r\n\t\t'arguments' in value\r\n\t)\r\n}\r\n\r\n/**\r\n * Determine if form dirty guard should be skipped for a navigation.\r\n *\r\n * @param to - Target page\r\n * @param from - Source page\r\n * @param excludePages - Pages to exclude from guard\r\n * @param onlyFromPages - Only guard from these pages (if specified)\r\n * @returns True if guard should be skipped\r\n */\r\nexport function shouldSkipFormGuard<TPage extends string>(\r\n\tto: TPage,\r\n\tfrom: TPage,\r\n\texcludePages: readonly TPage[],\r\n\tonlyFromPages: readonly TPage[] | undefined,\r\n): boolean {\r\n\t// Skip if navigating to excluded page\r\n\tif (excludePages.includes(to)) {\r\n\t\treturn true\r\n\t}\r\n\r\n\t// Skip if from page is not in onlyFromPages (if specified)\r\n\tif (onlyFromPages !== undefined && !onlyFromPages.includes(from)) {\r\n\t\treturn true\r\n\t}\r\n\r\n\treturn false\r\n}\r\n\r\n/**\r\n * Default result formatter for retrieval tools.\r\n * Returns content, score, and metadata.\r\n *\r\n * @param result - Scored result to format\r\n * @returns Formatted result object\r\n */\r\nexport function formatScoredResult(result: ScoredResult): unknown {\r\n\treturn {\r\n\t\tcontent: result.content,\r\n\t\tscore: result.score,\r\n\t\tmetadata: result.metadata,\r\n\t}\r\n}\r\n","/**\r\n * @mikesaintsg/core\r\n *\r\n * Shared constants for the core library.\r\n */\r\n\r\n// ============================================================================\r\n// Bridge Constants\r\n// ============================================================================\r\n\r\n/** Default timeout for bridge operations in milliseconds */\r\nexport const BRIDGE_DEFAULT_TIMEOUT = 30000\r\n\r\n/** Default retrieval limit for retrieval tool */\r\nexport const RETRIEVAL_DEFAULT_LIMIT = 10\r\n\r\n/** Maximum retrieval limit for retrieval tool */\r\nexport const RETRIEVAL_MAX_LIMIT = 100\r\n\r\n/** Default form dirty guard message */\r\nexport const FORM_DIRTY_DEFAULT_MESSAGE = 'You have unsaved changes. Are you sure you want to leave?'\r\n","/**\n * @mikesaintsg/core\n *\n * Factory functions for creating bridge instances.\n */\n\nimport type {\n\tToolCall,\n\tToolResult,\n\tToolCallBridgeOptions,\n\tToolCallBridgeInterface,\n\tRetrievalToolOptions,\n\tRetrievalToolCreated,\n\tToolSchema,\n\tJSONSchema7,\n\tFormDirtyGuardOptions,\n\tNavigationGuard,\n\tSessionPersistenceOptions,\n\tSessionPersistenceInterface,\n\tSerializableSession,\n\tSerializedSession,\n} from './types.js'\nimport {\n\tBRIDGE_DEFAULT_TIMEOUT,\n\tRETRIEVAL_DEFAULT_LIMIT,\n\tRETRIEVAL_MAX_LIMIT,\n\tFORM_DIRTY_DEFAULT_MESSAGE,\n} from './constants.js'\nimport {\n\tisToolCall,\n\tshouldSkipFormGuard,\n\tformatScoredResult,\n} from './helpers.js'\n\n// ============================================================================\n// Tool Call Bridge Factory\n// ============================================================================\n\n/**\n * Create a tool call bridge.\n *\n * @param options - Bridge configuration options\n * @returns A tool call bridge instance\n *\n * @example\n * ```ts\n * import { createToolRegistry } from '@mikesaintsg/contextprotocol'\n * import { createToolCallBridge } from '@mikesaintsg/core'\n *\n * const registry = createToolRegistry()\n * registry.register(weatherTool)\n *\n * const bridge = createToolCallBridge({\n * registry,\n * timeout: 30000,\n * onError: (error, toolCall) => console.error(`Tool ${toolCall.name} failed:`, error),\n * })\n *\n * // Execute tool calls from LLM response\n * const results = await bridge.execute(response.toolCalls)\n * ```\n */\nexport function createToolCallBridge(\n\toptions: ToolCallBridgeOptions,\n): ToolCallBridgeInterface {\n\tconst {\n\t\tregistry,\n\t\ttimeout = BRIDGE_DEFAULT_TIMEOUT,\n\t\tonError,\n\t\tonBeforeExecute,\n\t\tonAfterExecute,\n\t} = options\n\n\tasync function executeWithTimeout(toolCall: ToolCall): Promise<ToolResult> {\n\t\t// Check if tool exists\n\t\tif (!registry.has(toolCall.name)) {\n\t\t\treturn {\n\t\t\t\tcallId: toolCall.id,\n\t\t\t\tname: toolCall.name,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: `Tool not found: ${toolCall.name}`,\n\t\t\t}\n\t\t}\n\n\t\t// Call lifecycle hook\n\t\tonBeforeExecute?.(toolCall)\n\n\t\ttry {\n\t\t\t// Create timeout promise\n\t\t\tconst timeoutPromise = new Promise<never>((_, reject) => {\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\treject(new Error(`Tool execution timed out after ${timeout}ms`))\n\t\t\t\t}, timeout)\n\t\t\t})\n\n\t\t\t// Execute tool with timeout\n\t\t\tconst value = await Promise.race([\n\t\t\t\tregistry.execute(toolCall.name, toolCall.arguments),\n\t\t\t\ttimeoutPromise,\n\t\t\t])\n\n\t\t\t// Call lifecycle hook\n\t\t\tonAfterExecute?.(toolCall, value)\n\n\t\t\treturn {\n\t\t\t\tcallId: toolCall.id,\n\t\t\t\tname: toolCall.name,\n\t\t\t\tsuccess: true,\n\t\t\t\tvalue,\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Call error hook\n\t\t\tonError?.(error, toolCall)\n\n\t\t\tconst errorMessage = error instanceof Error\n\t\t\t\t? error.message\n\t\t\t\t: String(error)\n\n\t\t\treturn {\n\t\t\t\tcallId: toolCall.id,\n\t\t\t\tname: toolCall.name,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: errorMessage,\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\texecute(toolCallOrCalls: ToolCall | readonly ToolCall[]) {\n\t\t\tif (isToolCall(toolCallOrCalls)) {\n\t\t\t\treturn executeWithTimeout(toolCallOrCalls)\n\t\t\t}\n\t\t\treturn Promise.all(\n\t\t\t\t(toolCallOrCalls).map(tc => executeWithTimeout(tc)),\n\t\t\t)\n\t\t},\n\n\t\thasTool(name: string): boolean {\n\t\t\treturn registry.has(name)\n\t\t},\n\t} as ToolCallBridgeInterface\n}\n\n// ============================================================================\n// Retrieval Tool Factory\n// ============================================================================\n\n/**\n * Create a retrieval tool for use with contextprotocol tool registry.\n *\n * @param options - Retrieval tool configuration options\n * @returns A tool schema and handler for registration\n *\n * @example\n * ```ts\n * import { createVectorStore } from '@mikesaintsg/vectorstore'\n * import { createToolRegistry } from '@mikesaintsg/contextprotocol'\n * import { createRetrievalTool } from '@mikesaintsg/core'\n *\n * const vectorStore = createVectorStore({ ... })\n * const registry = createToolRegistry()\n *\n * const { schema, handler } = createRetrievalTool({\n * vectorStore,\n * name: 'search_docs',\n * description: 'Search documentation for relevant information',\n * defaultLimit: 5,\n * scoreThreshold: 0.7,\n * })\n *\n * registry.register({ ...schema, execute: handler })\n * ```\n */\nexport function createRetrievalTool<TMetadata = unknown>(\n\toptions: RetrievalToolOptions<TMetadata>,\n): RetrievalToolCreated {\n\tconst {\n\t\tvectorStore,\n\t\tname,\n\t\tdescription,\n\t\tdefaultLimit = RETRIEVAL_DEFAULT_LIMIT,\n\t\tmaxLimit = RETRIEVAL_MAX_LIMIT,\n\t\tscoreThreshold,\n\t\tformatResult = formatScoredResult,\n\t\textendParameters = {},\n\t\tbuildFilter,\n\t} = options\n\n\t// Build tool schema parameters\n\tconst parameters: JSONSchema7 = {\n\t\ttype: 'object',\n\t\tproperties: {\n\t\t\tquery: {\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'The search query to find relevant documents',\n\t\t\t},\n\t\t\tlimit: {\n\t\t\t\ttype: 'integer',\n\t\t\t\tdescription: `Maximum number of results to return (default: ${defaultLimit}, max: ${maxLimit})`,\n\t\t\t\tminimum: 1,\n\t\t\t\tmaximum: maxLimit,\n\t\t\t\tdefault: defaultLimit,\n\t\t\t},\n\t\t\t...extendParameters,\n\t\t},\n\t\trequired: ['query'],\n\t}\n\n\tconst schema: ToolSchema = {\n\t\tname,\n\t\tdescription,\n\t\tparameters,\n\t}\n\n\tasync function handler(\n\t\targs: Readonly<Record<string, unknown>>,\n\t): Promise<readonly unknown[]> {\n\t\tconst query = args.query\n\t\tif (typeof query !== 'string' || query.length === 0) {\n\t\t\treturn []\n\t\t}\n\n\t\tconst requestedLimit = args.limit\n\t\tlet limit = defaultLimit\n\t\tif (typeof requestedLimit === 'number' && Number.isInteger(requestedLimit)) {\n\t\t\tlimit = Math.min(Math.max(1, requestedLimit), maxLimit)\n\t\t}\n\n\t\t// Build filter if provided\n\t\tconst filter = buildFilter?.(args)\n\n\t\t// Search vectorstore - only include filter if defined\n\t\tconst searchOptions = filter !== undefined\n\t\t\t? { limit, filter }\n\t\t\t: { limit }\n\t\tconst results = await vectorStore.search(query, searchOptions)\n\n\t\t// Filter by score threshold\n\t\tlet filteredResults = results\n\t\tif (scoreThreshold !== undefined) {\n\t\t\tfilteredResults = results.filter(r => r.score >= scoreThreshold)\n\t\t}\n\n\t\t// Format results\n\t\treturn filteredResults.map(formatResult)\n\t}\n\n\treturn { schema, handler }\n}\n\n// ============================================================================\n// Form Dirty Guard Factory\n// ============================================================================\n\n/**\n * Create a navigation guard that prevents leaving when form is dirty.\n *\n * @param options - Form dirty guard configuration options\n * @returns A navigation guard function\n *\n * @example\n * ```ts\n * import { createForm } from '@mikesaintsg/form'\n * import { createFormDirtyGuard } from '@mikesaintsg/core'\n *\n * const form = createForm({ ... })\n *\n * const guard = createFormDirtyGuard({\n * form,\n * confirmFn: (message) => window.confirm(message),\n * message: 'You have unsaved changes. Continue?',\n * excludePages: ['settings'],\n * })\n *\n * // Use with router\n * router.beforeNavigate(guard)\n * ```\n */\nexport function createFormDirtyGuard<TFormData = unknown, TPage extends string = string>(\n\toptions: FormDirtyGuardOptions<TFormData, TPage>,\n): NavigationGuard<TPage> {\n\tconst {\n\t\tform,\n\t\tconfirmFn,\n\t\tmessage = FORM_DIRTY_DEFAULT_MESSAGE,\n\t\texcludePages = [],\n\t\tonlyFromPages,\n\t} = options\n\n\treturn async function guard(to: TPage, from: TPage): Promise<boolean> {\n\t\t// Check if we should skip guard for this navigation\n\t\tif (shouldSkipFormGuard(to, from, excludePages, onlyFromPages)) {\n\t\t\treturn true\n\t\t}\n\n\t\t// If form is not dirty, allow navigation\n\t\tif (!form.isDirty()) {\n\t\t\treturn true\n\t\t}\n\n\t\t// Form is dirty, ask for confirmation\n\t\treturn Promise.resolve(confirmFn(message))\n\t}\n}\n\n// ============================================================================\n// Session Persistence Factory\n// ============================================================================\n\n/**\n * Create a session persistence adapter for storing inference sessions.\n *\n * @param options - Session persistence configuration options\n * @returns A session persistence instance\n *\n * @example\n * ```ts\n * import { createDatabase } from '@mikesaintsg/indexeddb'\n * import { createSessionPersistence } from '@mikesaintsg/core'\n *\n * const db = await createDatabase({ name: 'sessions' })\n * const persistence = createSessionPersistence({\n * database: db,\n * storeName: 'chat_sessions',\n * autoprune: 7 * 24 * 60 * 60 * 1000, // 7 days\n * })\n *\n * // Save session\n * await persistence.save('session-1', session)\n *\n * // Load session\n * const savedSession = await persistence.load('session-1')\n * ```\n */\nexport function createSessionPersistence(\n\toptions: SessionPersistenceOptions,\n): SessionPersistenceInterface {\n\tconst {\n\t\tdatabase,\n\t\tstoreName,\n\t\tautoprune,\n\t\tonSaveError,\n\t} = options\n\n\tconst store = database.store<SerializedSession>(storeName)\n\n\tasync function pruneOldSessions(maxAgeMs: number): Promise<number> {\n\t\tconst now = Date.now()\n\t\tconst cutoff = now - maxAgeMs\n\n\t\tconst allSessions = await store.all()\n\t\tlet prunedCount = 0\n\n\t\tfor (const session of allSessions) {\n\t\t\tif (session.updatedAt < cutoff) {\n\t\t\t\tawait store.remove(session.id)\n\t\t\t\tprunedCount++\n\t\t\t}\n\t\t}\n\n\t\treturn prunedCount\n\t}\n\n\t// Auto-prune on creation if configured\n\tif (autoprune !== undefined && autoprune > 0) {\n\t\tvoid pruneOldSessions(autoprune)\n\t}\n\n\treturn {\n\t\tasync save(id: string, session: SerializableSession): Promise<void> {\n\t\t\ttry {\n\t\t\t\tconst serialized: SerializedSession = {\n\t\t\t\t\tid,\n\t\t\t\t\tmessages: [...session.getMessages()],\n\t\t\t\t\tmetadata: session.getMetadata(),\n\t\t\t\t\tupdatedAt: Date.now(),\n\t\t\t\t}\n\n\t\t\t\tawait store.set(serialized, id)\n\t\t\t} catch (error) {\n\t\t\t\tonSaveError?.(error, id)\n\t\t\t\tthrow error\n\t\t\t}\n\t\t},\n\n\t\tasync load(id: string): Promise<SerializedSession | undefined> {\n\t\t\treturn store.get(id)\n\t\t},\n\n\t\tasync delete(id: string): Promise<void> {\n\t\t\tawait store.remove(id)\n\t\t},\n\n\t\tasync list(): Promise<readonly string[]> {\n\t\t\tconst allSessions = await store.all()\n\t\t\treturn allSessions.map(s => s.id)\n\t\t},\n\n\t\tasync prune(maxAgeMs: number): Promise<number> {\n\t\t\treturn pruneOldSessions(maxAgeMs)\n\t\t},\n\t}\n}\n"],"names":["EcosystemError","message","cause","isEcosystemError","error","ok","value","err","isOk","result","isErr","unwrap","defaultValue","unwrapOrThrow","map","fn","mapErr","chain","computeContentHash","text","data","hashBuffer","b","isToolCall","shouldSkipFormGuard","to","from","excludePages","onlyFromPages","formatScoredResult","BRIDGE_DEFAULT_TIMEOUT","RETRIEVAL_DEFAULT_LIMIT","RETRIEVAL_MAX_LIMIT","FORM_DIRTY_DEFAULT_MESSAGE","createToolCallBridge","options","registry","timeout","onError","onBeforeExecute","onAfterExecute","executeWithTimeout","toolCall","timeoutPromise","_","reject","errorMessage","toolCallOrCalls","tc","name","createRetrievalTool","vectorStore","description","defaultLimit","maxLimit","scoreThreshold","formatResult","extendParameters","buildFilter","parameters","schema","handler","args","query","requestedLimit","limit","filter","searchOptions","results","filteredResults","r","createFormDirtyGuard","form","confirmFn","createSessionPersistence","database","storeName","autoprune","onSaveError","store","pruneOldSessions","maxAgeMs","cutoff","allSessions","prunedCount","session","id","serialized","s"],"mappings":"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"}
|