@animalabs/membrane 0.1.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/dist/context/index.d.ts +10 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +9 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/process.d.ts +22 -0
- package/dist/context/process.d.ts.map +1 -0
- package/dist/context/process.js +369 -0
- package/dist/context/process.js.map +1 -0
- package/dist/context/types.d.ts +118 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/context/types.js +60 -0
- package/dist/context/types.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/membrane.d.ts +96 -0
- package/dist/membrane.d.ts.map +1 -0
- package/dist/membrane.js +893 -0
- package/dist/membrane.js.map +1 -0
- package/dist/providers/anthropic.d.ts +36 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +265 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/index.d.ts +8 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +8 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/openai-compatible.d.ts +74 -0
- package/dist/providers/openai-compatible.d.ts.map +1 -0
- package/dist/providers/openai-compatible.js +412 -0
- package/dist/providers/openai-compatible.js.map +1 -0
- package/dist/providers/openai.d.ts +69 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +455 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/openrouter.d.ts +76 -0
- package/dist/providers/openrouter.d.ts.map +1 -0
- package/dist/providers/openrouter.js +492 -0
- package/dist/providers/openrouter.js.map +1 -0
- package/dist/transforms/chat.d.ts +52 -0
- package/dist/transforms/chat.d.ts.map +1 -0
- package/dist/transforms/chat.js +136 -0
- package/dist/transforms/chat.js.map +1 -0
- package/dist/transforms/index.d.ts +6 -0
- package/dist/transforms/index.d.ts.map +1 -0
- package/dist/transforms/index.js +6 -0
- package/dist/transforms/index.js.map +1 -0
- package/dist/transforms/prefill.d.ts +89 -0
- package/dist/transforms/prefill.d.ts.map +1 -0
- package/dist/transforms/prefill.js +401 -0
- package/dist/transforms/prefill.js.map +1 -0
- package/dist/types/config.d.ts +103 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +21 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/content.d.ts +81 -0
- package/dist/types/content.d.ts.map +1 -0
- package/dist/types/content.js +40 -0
- package/dist/types/content.js.map +1 -0
- package/dist/types/errors.d.ts +42 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +208 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/index.d.ts +18 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +9 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/message.d.ts +46 -0
- package/dist/types/message.d.ts.map +1 -0
- package/dist/types/message.js +38 -0
- package/dist/types/message.js.map +1 -0
- package/dist/types/provider.d.ts +155 -0
- package/dist/types/provider.d.ts.map +1 -0
- package/dist/types/provider.js +5 -0
- package/dist/types/provider.js.map +1 -0
- package/dist/types/request.d.ts +78 -0
- package/dist/types/request.d.ts.map +1 -0
- package/dist/types/request.js +5 -0
- package/dist/types/request.js.map +1 -0
- package/dist/types/response.d.ts +131 -0
- package/dist/types/response.d.ts.map +1 -0
- package/dist/types/response.js +7 -0
- package/dist/types/response.js.map +1 -0
- package/dist/types/streaming.d.ts +164 -0
- package/dist/types/streaming.d.ts.map +1 -0
- package/dist/types/streaming.js +5 -0
- package/dist/types/streaming.js.map +1 -0
- package/dist/types/tools.d.ts +71 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +5 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +5 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/stream-parser.d.ts +53 -0
- package/dist/utils/stream-parser.d.ts.map +1 -0
- package/dist/utils/stream-parser.js +359 -0
- package/dist/utils/stream-parser.js.map +1 -0
- package/dist/utils/tool-parser.d.ts +130 -0
- package/dist/utils/tool-parser.d.ts.map +1 -0
- package/dist/utils/tool-parser.js +571 -0
- package/dist/utils/tool-parser.js.map +1 -0
- package/package.json +37 -0
- package/src/context/index.ts +24 -0
- package/src/context/process.ts +520 -0
- package/src/context/types.ts +231 -0
- package/src/index.ts +23 -0
- package/src/membrane.ts +1174 -0
- package/src/providers/anthropic.ts +340 -0
- package/src/providers/index.ts +31 -0
- package/src/providers/openai-compatible.ts +570 -0
- package/src/providers/openai.ts +625 -0
- package/src/providers/openrouter.ts +662 -0
- package/src/transforms/chat.ts +212 -0
- package/src/transforms/index.ts +22 -0
- package/src/transforms/prefill.ts +585 -0
- package/src/types/config.ts +172 -0
- package/src/types/content.ts +181 -0
- package/src/types/errors.ts +277 -0
- package/src/types/index.ts +154 -0
- package/src/types/message.ts +89 -0
- package/src/types/provider.ts +249 -0
- package/src/types/request.ts +131 -0
- package/src/types/response.ts +223 -0
- package/src/types/streaming.ts +231 -0
- package/src/types/tools.ts +92 -0
- package/src/utils/index.ts +15 -0
- package/src/utils/stream-parser.ts +440 -0
- package/src/utils/tool-parser.ts +715 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context management types
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { NormalizedMessage, NormalizedResponse, AbortedResponse, GenerationConfig, ToolDefinition } from '../types/index.js';
|
|
6
|
+
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Cache Marker
|
|
9
|
+
// ============================================================================
|
|
10
|
+
|
|
11
|
+
export interface CacheMarker {
|
|
12
|
+
/** Message ID (from metadata.sourceId) */
|
|
13
|
+
messageId: string;
|
|
14
|
+
|
|
15
|
+
/** Index in the message array */
|
|
16
|
+
messageIndex: number;
|
|
17
|
+
|
|
18
|
+
/** Estimated tokens up to this point */
|
|
19
|
+
tokenEstimate: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// ============================================================================
|
|
23
|
+
// Context Config (per-call)
|
|
24
|
+
// ============================================================================
|
|
25
|
+
|
|
26
|
+
export interface ContextConfig {
|
|
27
|
+
/** Rolling configuration */
|
|
28
|
+
rolling: {
|
|
29
|
+
/** Threshold before roll triggers */
|
|
30
|
+
threshold: number;
|
|
31
|
+
|
|
32
|
+
/** Buffer to leave uncached after roll */
|
|
33
|
+
buffer: number;
|
|
34
|
+
|
|
35
|
+
/** Grace period before forced roll (optional) */
|
|
36
|
+
grace?: number;
|
|
37
|
+
|
|
38
|
+
/** Unit for threshold/buffer/grace (default: 'messages') */
|
|
39
|
+
unit?: 'messages' | 'tokens';
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/** Hard limits (always enforced) */
|
|
43
|
+
limits?: {
|
|
44
|
+
/** Maximum characters (default: 500000) */
|
|
45
|
+
maxCharacters?: number;
|
|
46
|
+
|
|
47
|
+
/** Maximum tokens */
|
|
48
|
+
maxTokens?: number;
|
|
49
|
+
|
|
50
|
+
/** Maximum messages */
|
|
51
|
+
maxMessages?: number;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/** Cache settings */
|
|
55
|
+
cache?: {
|
|
56
|
+
/** Enable caching (default: true) */
|
|
57
|
+
enabled?: boolean;
|
|
58
|
+
|
|
59
|
+
/** Number of cache points (default: 1, max: 4 for Anthropic) */
|
|
60
|
+
points?: 1 | 2 | 3 | 4;
|
|
61
|
+
|
|
62
|
+
/** Minimum tokens before caching (default: 1024) */
|
|
63
|
+
minTokens?: number;
|
|
64
|
+
|
|
65
|
+
/** Prefer user messages for cache markers (OpenRouter workaround) */
|
|
66
|
+
preferUserMessages?: boolean;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/** Custom token estimator (default: chars / 4) */
|
|
70
|
+
tokenEstimator?: (message: NormalizedMessage) => number;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ============================================================================
|
|
74
|
+
// Context State (persisted between calls)
|
|
75
|
+
// ============================================================================
|
|
76
|
+
|
|
77
|
+
export interface ContextState {
|
|
78
|
+
/** Current cache markers */
|
|
79
|
+
cacheMarkers: CacheMarker[];
|
|
80
|
+
|
|
81
|
+
/** Message IDs in current window (for continuity detection) */
|
|
82
|
+
windowMessageIds: string[];
|
|
83
|
+
|
|
84
|
+
/** Messages since last roll */
|
|
85
|
+
messagesSinceRoll: number;
|
|
86
|
+
|
|
87
|
+
/** Tokens since last roll */
|
|
88
|
+
tokensSinceRoll: number;
|
|
89
|
+
|
|
90
|
+
/** Whether we're in grace period */
|
|
91
|
+
inGracePeriod: boolean;
|
|
92
|
+
|
|
93
|
+
/** Last roll timestamp (ISO string) */
|
|
94
|
+
lastRollTime?: string;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ============================================================================
|
|
98
|
+
// Context Input (per-call request)
|
|
99
|
+
// ============================================================================
|
|
100
|
+
|
|
101
|
+
export interface ContextInput {
|
|
102
|
+
/** Conversation messages */
|
|
103
|
+
messages: NormalizedMessage[];
|
|
104
|
+
|
|
105
|
+
/** System prompt */
|
|
106
|
+
system?: string;
|
|
107
|
+
|
|
108
|
+
/** Tool definitions */
|
|
109
|
+
tools?: ToolDefinition[];
|
|
110
|
+
|
|
111
|
+
/** Generation config (model, maxTokens, etc.) */
|
|
112
|
+
config: GenerationConfig;
|
|
113
|
+
|
|
114
|
+
/** Context management config */
|
|
115
|
+
context: ContextConfig;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ============================================================================
|
|
119
|
+
// Context Info (what happened this call)
|
|
120
|
+
// ============================================================================
|
|
121
|
+
|
|
122
|
+
export interface ContextInfo {
|
|
123
|
+
/** Whether a roll occurred */
|
|
124
|
+
didRoll: boolean;
|
|
125
|
+
|
|
126
|
+
/** Number of messages dropped in roll */
|
|
127
|
+
messagesDropped: number;
|
|
128
|
+
|
|
129
|
+
/** Number of messages kept */
|
|
130
|
+
messagesKept: number;
|
|
131
|
+
|
|
132
|
+
/** Current cache markers */
|
|
133
|
+
cacheMarkers: CacheMarker[];
|
|
134
|
+
|
|
135
|
+
/** Estimated cached tokens */
|
|
136
|
+
cachedTokens: number;
|
|
137
|
+
|
|
138
|
+
/** Estimated uncached tokens */
|
|
139
|
+
uncachedTokens: number;
|
|
140
|
+
|
|
141
|
+
/** Total estimated tokens */
|
|
142
|
+
totalTokens: number;
|
|
143
|
+
|
|
144
|
+
/** Whether hard limit was hit */
|
|
145
|
+
hardLimitHit: boolean;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// ============================================================================
|
|
149
|
+
// Context Output (result of processContext)
|
|
150
|
+
// ============================================================================
|
|
151
|
+
|
|
152
|
+
export interface ContextOutput {
|
|
153
|
+
/** The LLM response (may be aborted) */
|
|
154
|
+
response: NormalizedResponse | AbortedResponse;
|
|
155
|
+
|
|
156
|
+
/** Updated state (save this for next call) */
|
|
157
|
+
state: ContextState;
|
|
158
|
+
|
|
159
|
+
/** Info about what happened */
|
|
160
|
+
info: ContextInfo;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// ============================================================================
|
|
164
|
+
// Stream Options
|
|
165
|
+
// ============================================================================
|
|
166
|
+
|
|
167
|
+
export interface ContextStreamOptions {
|
|
168
|
+
/** Callback for streaming chunks */
|
|
169
|
+
onChunk?: (chunk: string) => void;
|
|
170
|
+
|
|
171
|
+
/** Abort signal */
|
|
172
|
+
signal?: AbortSignal;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// ============================================================================
|
|
176
|
+
// Helpers
|
|
177
|
+
// ============================================================================
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Create initial empty state
|
|
181
|
+
*/
|
|
182
|
+
export function createInitialState(): ContextState {
|
|
183
|
+
return {
|
|
184
|
+
cacheMarkers: [],
|
|
185
|
+
windowMessageIds: [],
|
|
186
|
+
messagesSinceRoll: 0,
|
|
187
|
+
tokensSinceRoll: 0,
|
|
188
|
+
inGracePeriod: false,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Default token estimator (chars / 4)
|
|
194
|
+
*/
|
|
195
|
+
export function defaultTokenEstimator(message: NormalizedMessage): number {
|
|
196
|
+
let chars = 0;
|
|
197
|
+
for (const block of message.content) {
|
|
198
|
+
if (block.type === 'text') {
|
|
199
|
+
chars += block.text.length;
|
|
200
|
+
} else if (block.type === 'tool_result') {
|
|
201
|
+
const content = typeof block.content === 'string'
|
|
202
|
+
? block.content
|
|
203
|
+
: JSON.stringify(block.content);
|
|
204
|
+
chars += content.length;
|
|
205
|
+
} else if (block.type === 'image') {
|
|
206
|
+
// Images: ~1500 tokens regardless of size (Anthropic)
|
|
207
|
+
chars += 6000; // 1500 * 4
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return Math.ceil(chars / 4);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Default context config
|
|
215
|
+
*/
|
|
216
|
+
export const DEFAULT_CONTEXT_CONFIG: ContextConfig = {
|
|
217
|
+
rolling: {
|
|
218
|
+
threshold: 50,
|
|
219
|
+
buffer: 20,
|
|
220
|
+
unit: 'messages',
|
|
221
|
+
},
|
|
222
|
+
limits: {
|
|
223
|
+
maxCharacters: 500000,
|
|
224
|
+
},
|
|
225
|
+
cache: {
|
|
226
|
+
enabled: true,
|
|
227
|
+
points: 1,
|
|
228
|
+
minTokens: 1024,
|
|
229
|
+
preferUserMessages: true,
|
|
230
|
+
},
|
|
231
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Membrane - LLM middleware
|
|
3
|
+
*
|
|
4
|
+
* A selective boundary that transforms what passes through.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Core class
|
|
8
|
+
export { Membrane } from './membrane.js';
|
|
9
|
+
|
|
10
|
+
// Types
|
|
11
|
+
export * from './types/index.js';
|
|
12
|
+
|
|
13
|
+
// Transforms
|
|
14
|
+
export * from './transforms/index.js';
|
|
15
|
+
|
|
16
|
+
// Providers
|
|
17
|
+
export * from './providers/index.js';
|
|
18
|
+
|
|
19
|
+
// Utilities
|
|
20
|
+
export * from './utils/index.js';
|
|
21
|
+
|
|
22
|
+
// Context management
|
|
23
|
+
export * from './context/index.js';
|