recursive-llm-ts 4.4.1 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +375 -12
- package/bin/rlm-go +0 -0
- package/dist/bridge-interface.d.ts +19 -2
- package/dist/cache.d.ts +78 -0
- package/dist/cache.js +246 -0
- package/dist/config.d.ts +37 -0
- package/dist/config.js +162 -0
- package/dist/errors.d.ts +113 -0
- package/dist/errors.js +219 -0
- package/dist/events.d.ts +126 -0
- package/dist/events.js +77 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.js +38 -1
- package/dist/retry.d.ts +56 -0
- package/dist/retry.js +185 -0
- package/dist/rlm.d.ts +391 -13
- package/dist/rlm.js +815 -182
- package/dist/streaming.d.ts +96 -0
- package/dist/streaming.js +210 -0
- package/go/README.md +9 -1
- package/go/rlm/context_overflow.go +566 -0
- package/go/rlm/context_overflow_test.go +783 -0
- package/go/rlm/errors.go +161 -1
- package/go/rlm/rlm.go +10 -0
- package/go/rlm/structured.go +53 -0
- package/go/rlm/textrank.go +273 -0
- package/go/rlm/textrank_test.go +335 -0
- package/go/rlm/tfidf.go +225 -0
- package/go/rlm/tfidf_test.go +272 -0
- package/go/rlm/types.go +25 -2
- package/package.json +16 -4
package/dist/errors.js
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Structured error hierarchy for recursive-llm-ts.
|
|
4
|
+
*
|
|
5
|
+
* All library errors extend {@link RLMError}, which adds:
|
|
6
|
+
* - `code` – machine-readable error identifier
|
|
7
|
+
* - `retryable` – whether the caller should retry
|
|
8
|
+
* - `suggestion` – human-readable remediation hint
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.RLMAbortError = exports.RLMContextOverflowError = exports.RLMSchemaError = exports.RLMConfigError = exports.RLMBinaryError = exports.RLMProviderError = exports.RLMTimeoutError = exports.RLMRateLimitError = exports.RLMValidationError = exports.RLMError = void 0;
|
|
12
|
+
exports.classifyError = classifyError;
|
|
13
|
+
// ─── Base Error ──────────────────────────────────────────────────────────────
|
|
14
|
+
class RLMError extends Error {
|
|
15
|
+
constructor(message, opts) {
|
|
16
|
+
var _a;
|
|
17
|
+
super(message);
|
|
18
|
+
this.name = 'RLMError';
|
|
19
|
+
this.code = opts.code;
|
|
20
|
+
this.retryable = (_a = opts.retryable) !== null && _a !== void 0 ? _a : false;
|
|
21
|
+
this.suggestion = opts.suggestion;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.RLMError = RLMError;
|
|
25
|
+
// ─── Validation Errors ───────────────────────────────────────────────────────
|
|
26
|
+
/** Thrown when a structured output fails schema validation. */
|
|
27
|
+
class RLMValidationError extends RLMError {
|
|
28
|
+
constructor(opts) {
|
|
29
|
+
super(opts.message, {
|
|
30
|
+
code: 'VALIDATION',
|
|
31
|
+
retryable: true,
|
|
32
|
+
suggestion: 'The LLM returned output that did not match the Zod schema. Try a more capable model, simplify your schema, or increase maxRetries.',
|
|
33
|
+
});
|
|
34
|
+
this.name = 'RLMValidationError';
|
|
35
|
+
this.expected = opts.expected;
|
|
36
|
+
this.received = opts.received;
|
|
37
|
+
this.zodErrors = opts.zodErrors;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.RLMValidationError = RLMValidationError;
|
|
41
|
+
// ─── Rate Limit ──────────────────────────────────────────────────────────────
|
|
42
|
+
/** Thrown when the LLM provider returns a 429 rate limit response. */
|
|
43
|
+
class RLMRateLimitError extends RLMError {
|
|
44
|
+
constructor(opts) {
|
|
45
|
+
super(opts.message, {
|
|
46
|
+
code: 'RATE_LIMIT',
|
|
47
|
+
retryable: true,
|
|
48
|
+
suggestion: opts.retryAfter
|
|
49
|
+
? `Rate limited. Retry after ${opts.retryAfter}s.`
|
|
50
|
+
: 'Rate limited. Implement exponential backoff or upgrade your API tier.',
|
|
51
|
+
});
|
|
52
|
+
this.name = 'RLMRateLimitError';
|
|
53
|
+
this.retryAfter = opts.retryAfter;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.RLMRateLimitError = RLMRateLimitError;
|
|
57
|
+
// ─── Timeout ─────────────────────────────────────────────────────────────────
|
|
58
|
+
/** Thrown when an operation exceeds its time limit. */
|
|
59
|
+
class RLMTimeoutError extends RLMError {
|
|
60
|
+
constructor(opts) {
|
|
61
|
+
super(opts.message, {
|
|
62
|
+
code: 'TIMEOUT',
|
|
63
|
+
retryable: true,
|
|
64
|
+
suggestion: `Operation timed out after ${opts.elapsed}ms (limit: ${opts.limit}ms). Increase the timeout or reduce context size.`,
|
|
65
|
+
});
|
|
66
|
+
this.name = 'RLMTimeoutError';
|
|
67
|
+
this.elapsed = opts.elapsed;
|
|
68
|
+
this.limit = opts.limit;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.RLMTimeoutError = RLMTimeoutError;
|
|
72
|
+
// ─── Provider / API ──────────────────────────────────────────────────────────
|
|
73
|
+
/** Thrown when the LLM provider returns an HTTP error. */
|
|
74
|
+
class RLMProviderError extends RLMError {
|
|
75
|
+
constructor(opts) {
|
|
76
|
+
const retryable = opts.statusCode >= 500 || opts.statusCode === 429;
|
|
77
|
+
super(opts.message, {
|
|
78
|
+
code: 'PROVIDER',
|
|
79
|
+
retryable,
|
|
80
|
+
suggestion: retryable
|
|
81
|
+
? `Provider "${opts.provider}" returned ${opts.statusCode}. This is likely transient – retry with backoff.`
|
|
82
|
+
: `Provider "${opts.provider}" returned ${opts.statusCode}. Check your API key, model name, and request parameters.`,
|
|
83
|
+
});
|
|
84
|
+
this.name = 'RLMProviderError';
|
|
85
|
+
this.statusCode = opts.statusCode;
|
|
86
|
+
this.provider = opts.provider;
|
|
87
|
+
this.responseBody = opts.responseBody;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
exports.RLMProviderError = RLMProviderError;
|
|
91
|
+
// ─── Binary / Bridge ─────────────────────────────────────────────────────────
|
|
92
|
+
/** Thrown when the Go binary cannot be found or fails to start. */
|
|
93
|
+
class RLMBinaryError extends RLMError {
|
|
94
|
+
constructor(opts) {
|
|
95
|
+
super(opts.message, {
|
|
96
|
+
code: 'BINARY',
|
|
97
|
+
retryable: false,
|
|
98
|
+
suggestion: `Go binary not found at "${opts.binaryPath}". Build it with: npm run build:go (or node scripts/build-go-binary.js)`,
|
|
99
|
+
});
|
|
100
|
+
this.name = 'RLMBinaryError';
|
|
101
|
+
this.binaryPath = opts.binaryPath;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
exports.RLMBinaryError = RLMBinaryError;
|
|
105
|
+
// ─── Configuration ───────────────────────────────────────────────────────────
|
|
106
|
+
/** Thrown when the RLM configuration is invalid. */
|
|
107
|
+
class RLMConfigError extends RLMError {
|
|
108
|
+
constructor(opts) {
|
|
109
|
+
super(opts.message, {
|
|
110
|
+
code: 'CONFIG',
|
|
111
|
+
retryable: false,
|
|
112
|
+
suggestion: `Invalid configuration for "${opts.field}". Check the RLMConfig documentation.`,
|
|
113
|
+
});
|
|
114
|
+
this.name = 'RLMConfigError';
|
|
115
|
+
this.field = opts.field;
|
|
116
|
+
this.value = opts.value;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.RLMConfigError = RLMConfigError;
|
|
120
|
+
// ─── Schema ──────────────────────────────────────────────────────────────────
|
|
121
|
+
/** Thrown when a JSON Schema is malformed or unsupported. */
|
|
122
|
+
class RLMSchemaError extends RLMError {
|
|
123
|
+
constructor(opts) {
|
|
124
|
+
super(opts.message, {
|
|
125
|
+
code: 'SCHEMA',
|
|
126
|
+
retryable: false,
|
|
127
|
+
suggestion: `Schema issue at "${opts.path}": ${opts.constraint}. Simplify your Zod schema or check for unsupported types.`,
|
|
128
|
+
});
|
|
129
|
+
this.name = 'RLMSchemaError';
|
|
130
|
+
this.path = opts.path;
|
|
131
|
+
this.constraint = opts.constraint;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
exports.RLMSchemaError = RLMSchemaError;
|
|
135
|
+
// ─── Context Overflow ─────────────────────────────────────────────────────────
|
|
136
|
+
/** Thrown when the request exceeds the model's context window. */
|
|
137
|
+
class RLMContextOverflowError extends RLMError {
|
|
138
|
+
constructor(opts) {
|
|
139
|
+
super(opts.message, {
|
|
140
|
+
code: 'CONTEXT_OVERFLOW',
|
|
141
|
+
retryable: true,
|
|
142
|
+
suggestion: `Request has ${opts.requestTokens} tokens but model limit is ${opts.modelLimit}. ` +
|
|
143
|
+
'Enable context_overflow handling or reduce your context size.',
|
|
144
|
+
});
|
|
145
|
+
this.name = 'RLMContextOverflowError';
|
|
146
|
+
this.modelLimit = opts.modelLimit;
|
|
147
|
+
this.requestTokens = opts.requestTokens;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
exports.RLMContextOverflowError = RLMContextOverflowError;
|
|
151
|
+
// ─── Abort ───────────────────────────────────────────────────────────────────
|
|
152
|
+
/** Thrown when an operation is aborted via AbortController. */
|
|
153
|
+
class RLMAbortError extends RLMError {
|
|
154
|
+
constructor(message = 'Operation was aborted') {
|
|
155
|
+
super(message, {
|
|
156
|
+
code: 'ABORTED',
|
|
157
|
+
retryable: false,
|
|
158
|
+
suggestion: 'The operation was cancelled. This is expected when using AbortController.',
|
|
159
|
+
});
|
|
160
|
+
this.name = 'RLMAbortError';
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
exports.RLMAbortError = RLMAbortError;
|
|
164
|
+
// ─── Error Classification Helper ─────────────────────────────────────────────
|
|
165
|
+
/**
|
|
166
|
+
* Classify a raw Error into the appropriate RLM error type.
|
|
167
|
+
* Used internally by the bridge layer to wrap Go binary errors.
|
|
168
|
+
*/
|
|
169
|
+
function classifyError(err, context) {
|
|
170
|
+
var _a;
|
|
171
|
+
const msg = typeof err === 'string' ? err : err.message;
|
|
172
|
+
// Context overflow
|
|
173
|
+
if (msg.toLowerCase().includes('maximum context length') || msg.toLowerCase().includes('context_length_exceeded') || msg.toLowerCase().includes('too many input tokens')) {
|
|
174
|
+
const limitMatch = msg.match(/maximum context length is (\d[\d,]*)/i);
|
|
175
|
+
const requestMatch = msg.match(/(?:has|requested) (\d[\d,]*)\s*(?:input )?tokens/i);
|
|
176
|
+
const modelLimit = limitMatch ? parseInt(limitMatch[1].replace(/,/g, ''), 10) : 0;
|
|
177
|
+
const requestTokens = requestMatch ? parseInt(requestMatch[1].replace(/,/g, ''), 10) : 0;
|
|
178
|
+
return new RLMContextOverflowError({ message: msg, modelLimit, requestTokens });
|
|
179
|
+
}
|
|
180
|
+
// Rate limit
|
|
181
|
+
if (msg.includes('429') || msg.toLowerCase().includes('rate limit') || msg.toLowerCase().includes('too many requests')) {
|
|
182
|
+
const retryMatch = msg.match(/retry.after[:\s]+(\d+)/i);
|
|
183
|
+
return new RLMRateLimitError({
|
|
184
|
+
message: msg,
|
|
185
|
+
retryAfter: retryMatch ? parseInt(retryMatch[1], 10) : undefined,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
// Timeout
|
|
189
|
+
if (msg.toLowerCase().includes('timeout') || msg.includes('ETIMEDOUT') || msg.includes('ESOCKETTIMEDOUT')) {
|
|
190
|
+
return new RLMTimeoutError({ message: msg, elapsed: 0, limit: 0 });
|
|
191
|
+
}
|
|
192
|
+
// Binary not found
|
|
193
|
+
if ((msg.includes('not found') && msg.includes('binary')) || (msg.includes('ENOENT') && (context === null || context === void 0 ? void 0 : context.binaryPath))) {
|
|
194
|
+
return new RLMBinaryError({ message: msg, binaryPath: (_a = context === null || context === void 0 ? void 0 : context.binaryPath) !== null && _a !== void 0 ? _a : 'unknown' });
|
|
195
|
+
}
|
|
196
|
+
// Provider errors with HTTP codes
|
|
197
|
+
const statusMatch = msg.match(/(?:status|code)[:\s]+(\d{3})/i);
|
|
198
|
+
if (statusMatch) {
|
|
199
|
+
const statusCode = parseInt(statusMatch[1], 10);
|
|
200
|
+
if (statusCode === 429) {
|
|
201
|
+
return new RLMRateLimitError({ message: msg });
|
|
202
|
+
}
|
|
203
|
+
return new RLMProviderError({
|
|
204
|
+
message: msg,
|
|
205
|
+
statusCode,
|
|
206
|
+
provider: (context === null || context === void 0 ? void 0 : context.provider) || 'unknown',
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
// Validation
|
|
210
|
+
if (msg.toLowerCase().includes('validation') || msg.toLowerCase().includes('schema') || msg.toLowerCase().includes('parse')) {
|
|
211
|
+
return new RLMValidationError({
|
|
212
|
+
message: msg,
|
|
213
|
+
expected: undefined,
|
|
214
|
+
received: undefined,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
// Fallback
|
|
218
|
+
return new RLMError(msg, { code: 'UNKNOWN', retryable: false });
|
|
219
|
+
}
|
package/dist/events.d.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event system for recursive-llm-ts.
|
|
3
|
+
*
|
|
4
|
+
* Provides typed event emission for monitoring LLM operations,
|
|
5
|
+
* validation retries, recursion progress, and more.
|
|
6
|
+
*/
|
|
7
|
+
export interface RLMEventMap {
|
|
8
|
+
/** Fired when an LLM API call is made */
|
|
9
|
+
'llm_call': LLMCallEvent;
|
|
10
|
+
/** Fired when an LLM API call completes */
|
|
11
|
+
'llm_response': LLMResponseEvent;
|
|
12
|
+
/** Fired when a validation retry occurs */
|
|
13
|
+
'validation_retry': ValidationRetryEvent;
|
|
14
|
+
/** Fired when recursion depth changes */
|
|
15
|
+
'recursion': RecursionEvent;
|
|
16
|
+
/** Fired when meta-agent optimizes a query */
|
|
17
|
+
'meta_agent': MetaAgentEvent;
|
|
18
|
+
/** Fired on any error */
|
|
19
|
+
'error': ErrorEvent;
|
|
20
|
+
/** Fired when a completion starts */
|
|
21
|
+
'completion_start': CompletionStartEvent;
|
|
22
|
+
/** Fired when a completion ends */
|
|
23
|
+
'completion_end': CompletionEndEvent;
|
|
24
|
+
/** Fired when a cache lookup occurs */
|
|
25
|
+
'cache': CacheEvent;
|
|
26
|
+
/** Fired when a retry occurs */
|
|
27
|
+
'retry': RetryEvent;
|
|
28
|
+
}
|
|
29
|
+
export type RLMEventType = keyof RLMEventMap;
|
|
30
|
+
interface BaseEvent {
|
|
31
|
+
timestamp: number;
|
|
32
|
+
type: string;
|
|
33
|
+
}
|
|
34
|
+
export interface LLMCallEvent extends BaseEvent {
|
|
35
|
+
type: 'llm_call';
|
|
36
|
+
model: string;
|
|
37
|
+
queryLength: number;
|
|
38
|
+
contextLength: number;
|
|
39
|
+
}
|
|
40
|
+
export interface LLMResponseEvent extends BaseEvent {
|
|
41
|
+
type: 'llm_response';
|
|
42
|
+
model: string;
|
|
43
|
+
duration: number;
|
|
44
|
+
tokenCount?: number;
|
|
45
|
+
}
|
|
46
|
+
export interface ValidationRetryEvent extends BaseEvent {
|
|
47
|
+
type: 'validation_retry';
|
|
48
|
+
attempt: number;
|
|
49
|
+
maxRetries: number;
|
|
50
|
+
error: string;
|
|
51
|
+
}
|
|
52
|
+
export interface RecursionEvent extends BaseEvent {
|
|
53
|
+
type: 'recursion';
|
|
54
|
+
depth: number;
|
|
55
|
+
maxDepth: number;
|
|
56
|
+
iteration: number;
|
|
57
|
+
}
|
|
58
|
+
export interface MetaAgentEvent extends BaseEvent {
|
|
59
|
+
type: 'meta_agent';
|
|
60
|
+
originalQuery: string;
|
|
61
|
+
optimizedQuery: string;
|
|
62
|
+
skipped: boolean;
|
|
63
|
+
reason?: string;
|
|
64
|
+
}
|
|
65
|
+
export interface ErrorEvent extends BaseEvent {
|
|
66
|
+
type: 'error';
|
|
67
|
+
error: Error;
|
|
68
|
+
operation: string;
|
|
69
|
+
}
|
|
70
|
+
export interface CompletionStartEvent extends BaseEvent {
|
|
71
|
+
type: 'completion_start';
|
|
72
|
+
model: string;
|
|
73
|
+
query: string;
|
|
74
|
+
contextLength: number;
|
|
75
|
+
structured: boolean;
|
|
76
|
+
}
|
|
77
|
+
export interface CompletionEndEvent extends BaseEvent {
|
|
78
|
+
type: 'completion_end';
|
|
79
|
+
model: string;
|
|
80
|
+
duration: number;
|
|
81
|
+
stats: {
|
|
82
|
+
llm_calls: number;
|
|
83
|
+
iterations: number;
|
|
84
|
+
depth: number;
|
|
85
|
+
};
|
|
86
|
+
cached: boolean;
|
|
87
|
+
}
|
|
88
|
+
export interface CacheEvent extends BaseEvent {
|
|
89
|
+
type: 'cache';
|
|
90
|
+
action: 'hit' | 'miss' | 'store';
|
|
91
|
+
key?: string;
|
|
92
|
+
}
|
|
93
|
+
export interface RetryEvent extends BaseEvent {
|
|
94
|
+
type: 'retry';
|
|
95
|
+
attempt: number;
|
|
96
|
+
maxRetries: number;
|
|
97
|
+
delay: number;
|
|
98
|
+
error: string;
|
|
99
|
+
}
|
|
100
|
+
type EventListener<T> = (event: T) => void;
|
|
101
|
+
/**
|
|
102
|
+
* Typed event emitter for RLM operations.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```typescript
|
|
106
|
+
* const rlm = new RLM('gpt-4o-mini');
|
|
107
|
+
* rlm.on('llm_call', (event) => console.log('LLM call:', event.model));
|
|
108
|
+
* rlm.on('error', (event) => reportToSentry(event.error));
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
export declare class RLMEventEmitter {
|
|
112
|
+
private listeners;
|
|
113
|
+
/** Register an event listener */
|
|
114
|
+
on<K extends RLMEventType>(event: K, listener: EventListener<RLMEventMap[K]>): this;
|
|
115
|
+
/** Register a one-time event listener */
|
|
116
|
+
once<K extends RLMEventType>(event: K, listener: EventListener<RLMEventMap[K]>): this;
|
|
117
|
+
/** Remove an event listener */
|
|
118
|
+
off<K extends RLMEventType>(event: K, listener: EventListener<RLMEventMap[K]>): this;
|
|
119
|
+
/** Remove all listeners for an event (or all events) */
|
|
120
|
+
removeAllListeners(event?: RLMEventType): this;
|
|
121
|
+
/** Emit an event to all registered listeners */
|
|
122
|
+
emit<K extends RLMEventType>(event: K, data: RLMEventMap[K]): void;
|
|
123
|
+
/** Get the number of listeners for an event */
|
|
124
|
+
listenerCount(event: RLMEventType): number;
|
|
125
|
+
}
|
|
126
|
+
export {};
|
package/dist/events.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Event system for recursive-llm-ts.
|
|
4
|
+
*
|
|
5
|
+
* Provides typed event emission for monitoring LLM operations,
|
|
6
|
+
* validation retries, recursion progress, and more.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.RLMEventEmitter = void 0;
|
|
10
|
+
// ─── Event Emitter ───────────────────────────────────────────────────────────
|
|
11
|
+
/**
|
|
12
|
+
* Typed event emitter for RLM operations.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const rlm = new RLM('gpt-4o-mini');
|
|
17
|
+
* rlm.on('llm_call', (event) => console.log('LLM call:', event.model));
|
|
18
|
+
* rlm.on('error', (event) => reportToSentry(event.error));
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
class RLMEventEmitter {
|
|
22
|
+
constructor() {
|
|
23
|
+
this.listeners = new Map();
|
|
24
|
+
}
|
|
25
|
+
/** Register an event listener */
|
|
26
|
+
on(event, listener) {
|
|
27
|
+
if (!this.listeners.has(event)) {
|
|
28
|
+
this.listeners.set(event, new Set());
|
|
29
|
+
}
|
|
30
|
+
this.listeners.get(event).add(listener);
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
/** Register a one-time event listener */
|
|
34
|
+
once(event, listener) {
|
|
35
|
+
const wrapper = (e) => {
|
|
36
|
+
this.off(event, wrapper);
|
|
37
|
+
listener(e);
|
|
38
|
+
};
|
|
39
|
+
return this.on(event, wrapper);
|
|
40
|
+
}
|
|
41
|
+
/** Remove an event listener */
|
|
42
|
+
off(event, listener) {
|
|
43
|
+
var _a;
|
|
44
|
+
(_a = this.listeners.get(event)) === null || _a === void 0 ? void 0 : _a.delete(listener);
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
/** Remove all listeners for an event (or all events) */
|
|
48
|
+
removeAllListeners(event) {
|
|
49
|
+
if (event) {
|
|
50
|
+
this.listeners.delete(event);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
this.listeners.clear();
|
|
54
|
+
}
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
/** Emit an event to all registered listeners */
|
|
58
|
+
emit(event, data) {
|
|
59
|
+
const eventListeners = this.listeners.get(event);
|
|
60
|
+
if (eventListeners) {
|
|
61
|
+
for (const listener of eventListeners) {
|
|
62
|
+
try {
|
|
63
|
+
listener(data);
|
|
64
|
+
}
|
|
65
|
+
catch (_a) {
|
|
66
|
+
// Don't let listener errors break the emitter
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/** Get the number of listeners for an event */
|
|
72
|
+
listenerCount(event) {
|
|
73
|
+
var _a, _b;
|
|
74
|
+
return (_b = (_a = this.listeners.get(event)) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : 0;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.RLMEventEmitter = RLMEventEmitter;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
export { RLM } from './rlm';
|
|
2
|
-
export { RLMConfig, RLMResult, RLMStats, MetaAgentConfig, ObservabilityConfig, TraceEvent, FileStorageConfig } from './bridge-interface';
|
|
1
|
+
export { RLM, RLMBuilder, RLMCompletionResult, RLMResultFormatter } from './rlm';
|
|
2
|
+
export { RLMConfig, RLMResult, RLMStats, MetaAgentConfig, ObservabilityConfig, TraceEvent, FileStorageConfig, ContextOverflowConfig } from './bridge-interface';
|
|
3
3
|
export { BridgeType } from './bridge-factory';
|
|
4
4
|
export { StructuredRLMResult, SubTask, CoordinatorConfig, SchemaDecomposition } from './structured-types';
|
|
5
|
+
export { RLMExtendedConfig, ValidationResult, ValidationIssue, ValidationLevel, validateConfig, assertValidConfig } from './config';
|
|
6
|
+
export { RLMError, RLMValidationError, RLMRateLimitError, RLMTimeoutError, RLMProviderError, RLMBinaryError, RLMConfigError, RLMSchemaError, RLMContextOverflowError, RLMAbortError, classifyError, } from './errors';
|
|
7
|
+
export { RLMStream, StreamOptions, StreamChunk, StreamChunkType, TextStreamChunk, PartialObjectStreamChunk, UsageStreamChunk, ErrorStreamChunk, DoneStreamChunk, createSimulatedStream, } from './streaming';
|
|
8
|
+
export { RLMCache, CacheConfig, CacheStats, CacheProvider, MemoryCache, FileCache } from './cache';
|
|
9
|
+
export { RetryConfig, FallbackConfig, withRetry, withFallback } from './retry';
|
|
10
|
+
export { RLMEventEmitter, RLMEventMap, RLMEventType, LLMCallEvent, LLMResponseEvent, ValidationRetryEvent, RecursionEvent, MetaAgentEvent, ErrorEvent, CompletionStartEvent, CompletionEndEvent, CacheEvent, RetryEvent, } from './events';
|
|
5
11
|
export { RLMAgentCoordinator } from './coordinator';
|
|
6
12
|
export { FileContextBuilder, FileStorageProvider, FileStorageResult, FileEntry, LocalFileStorage, S3FileStorage, S3StorageError, buildFileContext, } from './file-storage';
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,47 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.buildFileContext = exports.S3StorageError = exports.S3FileStorage = exports.LocalFileStorage = exports.FileContextBuilder = exports.RLMAgentCoordinator = exports.RLM = void 0;
|
|
3
|
+
exports.buildFileContext = exports.S3StorageError = exports.S3FileStorage = exports.LocalFileStorage = exports.FileContextBuilder = exports.RLMAgentCoordinator = exports.RLMEventEmitter = exports.withFallback = exports.withRetry = exports.FileCache = exports.MemoryCache = exports.RLMCache = exports.createSimulatedStream = exports.RLMStream = exports.classifyError = exports.RLMAbortError = exports.RLMContextOverflowError = exports.RLMSchemaError = exports.RLMConfigError = exports.RLMBinaryError = exports.RLMProviderError = exports.RLMTimeoutError = exports.RLMRateLimitError = exports.RLMValidationError = exports.RLMError = exports.assertValidConfig = exports.validateConfig = exports.RLMResultFormatter = exports.RLMBuilder = exports.RLM = void 0;
|
|
4
|
+
// ─── Core ────────────────────────────────────────────────────────────────────
|
|
4
5
|
var rlm_1 = require("./rlm");
|
|
5
6
|
Object.defineProperty(exports, "RLM", { enumerable: true, get: function () { return rlm_1.RLM; } });
|
|
7
|
+
Object.defineProperty(exports, "RLMBuilder", { enumerable: true, get: function () { return rlm_1.RLMBuilder; } });
|
|
8
|
+
Object.defineProperty(exports, "RLMResultFormatter", { enumerable: true, get: function () { return rlm_1.RLMResultFormatter; } });
|
|
9
|
+
var config_1 = require("./config");
|
|
10
|
+
Object.defineProperty(exports, "validateConfig", { enumerable: true, get: function () { return config_1.validateConfig; } });
|
|
11
|
+
Object.defineProperty(exports, "assertValidConfig", { enumerable: true, get: function () { return config_1.assertValidConfig; } });
|
|
12
|
+
// ─── Errors ──────────────────────────────────────────────────────────────────
|
|
13
|
+
var errors_1 = require("./errors");
|
|
14
|
+
Object.defineProperty(exports, "RLMError", { enumerable: true, get: function () { return errors_1.RLMError; } });
|
|
15
|
+
Object.defineProperty(exports, "RLMValidationError", { enumerable: true, get: function () { return errors_1.RLMValidationError; } });
|
|
16
|
+
Object.defineProperty(exports, "RLMRateLimitError", { enumerable: true, get: function () { return errors_1.RLMRateLimitError; } });
|
|
17
|
+
Object.defineProperty(exports, "RLMTimeoutError", { enumerable: true, get: function () { return errors_1.RLMTimeoutError; } });
|
|
18
|
+
Object.defineProperty(exports, "RLMProviderError", { enumerable: true, get: function () { return errors_1.RLMProviderError; } });
|
|
19
|
+
Object.defineProperty(exports, "RLMBinaryError", { enumerable: true, get: function () { return errors_1.RLMBinaryError; } });
|
|
20
|
+
Object.defineProperty(exports, "RLMConfigError", { enumerable: true, get: function () { return errors_1.RLMConfigError; } });
|
|
21
|
+
Object.defineProperty(exports, "RLMSchemaError", { enumerable: true, get: function () { return errors_1.RLMSchemaError; } });
|
|
22
|
+
Object.defineProperty(exports, "RLMContextOverflowError", { enumerable: true, get: function () { return errors_1.RLMContextOverflowError; } });
|
|
23
|
+
Object.defineProperty(exports, "RLMAbortError", { enumerable: true, get: function () { return errors_1.RLMAbortError; } });
|
|
24
|
+
Object.defineProperty(exports, "classifyError", { enumerable: true, get: function () { return errors_1.classifyError; } });
|
|
25
|
+
// ─── Streaming ───────────────────────────────────────────────────────────────
|
|
26
|
+
var streaming_1 = require("./streaming");
|
|
27
|
+
Object.defineProperty(exports, "RLMStream", { enumerable: true, get: function () { return streaming_1.RLMStream; } });
|
|
28
|
+
Object.defineProperty(exports, "createSimulatedStream", { enumerable: true, get: function () { return streaming_1.createSimulatedStream; } });
|
|
29
|
+
// ─── Cache ───────────────────────────────────────────────────────────────────
|
|
30
|
+
var cache_1 = require("./cache");
|
|
31
|
+
Object.defineProperty(exports, "RLMCache", { enumerable: true, get: function () { return cache_1.RLMCache; } });
|
|
32
|
+
Object.defineProperty(exports, "MemoryCache", { enumerable: true, get: function () { return cache_1.MemoryCache; } });
|
|
33
|
+
Object.defineProperty(exports, "FileCache", { enumerable: true, get: function () { return cache_1.FileCache; } });
|
|
34
|
+
// ─── Retry / Resilience ──────────────────────────────────────────────────────
|
|
35
|
+
var retry_1 = require("./retry");
|
|
36
|
+
Object.defineProperty(exports, "withRetry", { enumerable: true, get: function () { return retry_1.withRetry; } });
|
|
37
|
+
Object.defineProperty(exports, "withFallback", { enumerable: true, get: function () { return retry_1.withFallback; } });
|
|
38
|
+
// ─── Events ──────────────────────────────────────────────────────────────────
|
|
39
|
+
var events_1 = require("./events");
|
|
40
|
+
Object.defineProperty(exports, "RLMEventEmitter", { enumerable: true, get: function () { return events_1.RLMEventEmitter; } });
|
|
41
|
+
// ─── Coordinator ─────────────────────────────────────────────────────────────
|
|
6
42
|
var coordinator_1 = require("./coordinator");
|
|
7
43
|
Object.defineProperty(exports, "RLMAgentCoordinator", { enumerable: true, get: function () { return coordinator_1.RLMAgentCoordinator; } });
|
|
44
|
+
// ─── File Storage ────────────────────────────────────────────────────────────
|
|
8
45
|
var file_storage_1 = require("./file-storage");
|
|
9
46
|
Object.defineProperty(exports, "FileContextBuilder", { enumerable: true, get: function () { return file_storage_1.FileContextBuilder; } });
|
|
10
47
|
Object.defineProperty(exports, "LocalFileStorage", { enumerable: true, get: function () { return file_storage_1.LocalFileStorage; } });
|
package/dist/retry.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry and resilience layer for recursive-llm-ts.
|
|
3
|
+
*
|
|
4
|
+
* Provides configurable retry with exponential backoff, jitter,
|
|
5
|
+
* and provider fallback chains.
|
|
6
|
+
*/
|
|
7
|
+
export interface RetryConfig {
|
|
8
|
+
/** Maximum number of retries (default: 3) */
|
|
9
|
+
maxRetries?: number;
|
|
10
|
+
/** Backoff strategy (default: 'exponential') */
|
|
11
|
+
backoff?: 'exponential' | 'linear' | 'fixed';
|
|
12
|
+
/** Base delay in milliseconds (default: 1000) */
|
|
13
|
+
baseDelay?: number;
|
|
14
|
+
/** Maximum delay in milliseconds (default: 30000) */
|
|
15
|
+
maxDelay?: number;
|
|
16
|
+
/** Add jitter to delays (default: true) */
|
|
17
|
+
jitter?: boolean;
|
|
18
|
+
/** Error types that should be retried */
|
|
19
|
+
retryableErrors?: string[];
|
|
20
|
+
/** Called before each retry with retry info */
|
|
21
|
+
onRetry?: (attempt: number, error: Error, delay: number) => void;
|
|
22
|
+
}
|
|
23
|
+
/** Fallback model configuration */
|
|
24
|
+
export interface FallbackConfig {
|
|
25
|
+
/** Ordered list of fallback models to try */
|
|
26
|
+
models?: string[];
|
|
27
|
+
/** Strategy for fallback selection */
|
|
28
|
+
strategy?: 'sequential' | 'round-robin';
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Execute a function with retry logic.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* const result = await withRetry(
|
|
36
|
+
* () => rlm.completion(query, context),
|
|
37
|
+
* { maxRetries: 3, backoff: 'exponential' }
|
|
38
|
+
* );
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function withRetry<T>(fn: () => Promise<T>, config?: RetryConfig, signal?: AbortSignal): Promise<T>;
|
|
42
|
+
/**
|
|
43
|
+
* Execute a function with fallback models.
|
|
44
|
+
* Tries each model in order until one succeeds.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* const result = await withFallback(
|
|
49
|
+
* (model) => rlm.completion(query, context, model),
|
|
50
|
+
* { models: ['gpt-4o', 'claude-sonnet-4-20250514', 'gemini-2.0-flash'] }
|
|
51
|
+
* );
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export declare function withFallback<T>(fn: (model: string) => Promise<T>, fallbackConfig: FallbackConfig, retryConfig?: RetryConfig, signal?: AbortSignal): Promise<T & {
|
|
55
|
+
_usedModel?: string;
|
|
56
|
+
}>;
|