@animalabs/membrane 0.5.43 → 0.5.44
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/formatters/index.d.ts +1 -0
- package/dist/formatters/index.js +1 -0
- package/dist/formatters/index.js.map +1 -1
- package/dist/formatters/pseudo-prefill.d.ts +71 -0
- package/dist/formatters/pseudo-prefill.d.ts.map +1 -0
- package/dist/formatters/pseudo-prefill.js +410 -0
- package/dist/formatters/pseudo-prefill.js.map +1 -0
- package/dist/formatters/types.d.ts +4 -0
- package/dist/membrane.d.ts.map +1 -1
- package/dist/membrane.js +6 -1
- package/dist/membrane.js.map +1 -1
- package/dist/providers/bedrock.js +2 -11
- package/dist/providers/bedrock.js.map +1 -1
- package/dist/providers/gemini.js +2 -11
- package/dist/providers/gemini.js.map +1 -1
- package/dist/providers/openai-compatible.js +15 -25
- package/dist/providers/openai-compatible.js.map +1 -1
- package/dist/providers/openai-completions.js +24 -48
- package/dist/providers/openai-completions.js.map +1 -1
- package/dist/providers/openai-responses.js +1 -6
- package/dist/providers/openai-responses.js.map +1 -1
- package/dist/providers/openai.js +15 -25
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/openrouter.js +16 -35
- package/dist/providers/openrouter.js.map +1 -1
- package/dist/providers/utils.d.ts +0 -38
- package/dist/providers/utils.d.ts.map +1 -1
- package/dist/providers/utils.js +0 -86
- package/dist/providers/utils.js.map +1 -1
- package/dist/transforms/prefill.d.ts.map +1 -1
- package/dist/transforms/prefill.js +44 -45
- package/dist/transforms/prefill.js.map +1 -1
- package/dist/types/request.d.ts +0 -8
- package/dist/types/request.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/membrane.ts +6 -1
|
@@ -5,4 +5,5 @@ export type { PrefillFormatter, StreamParser, FormatterConfig, BuildOptions, Bui
|
|
|
5
5
|
export { AnthropicXmlFormatter, type AnthropicXmlFormatterConfig } from './anthropic-xml.js';
|
|
6
6
|
export { NativeFormatter, type NativeFormatterConfig } from './native.js';
|
|
7
7
|
export { CompletionsFormatter, type CompletionsFormatterConfig } from './completions.js';
|
|
8
|
+
export { PseudoPrefillFormatter, type PseudoPrefillFormatterConfig } from './pseudo-prefill.js';
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/formatters/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/formatters/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,OAAO,EAAE,qBAAqB,EAAoC,MAAM,oBAAoB,CAAC;AAC7F,OAAO,EAAE,eAAe,EAA8B,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,oBAAoB,EAAmC,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/formatters/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,OAAO,EAAE,qBAAqB,EAAoC,MAAM,oBAAoB,CAAC;AAC7F,OAAO,EAAE,eAAe,EAA8B,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,oBAAoB,EAAmC,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,sBAAsB,EAAqC,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pseudo-Prefill Formatter
|
|
3
|
+
*
|
|
4
|
+
* Recovers prefill-like behavior for models that don't support native
|
|
5
|
+
* assistant message prefill (e.g., Sonnet 4.6, Opus 4.6). Uses a CLI
|
|
6
|
+
* simulation framing trick:
|
|
7
|
+
*
|
|
8
|
+
* System: "The assistant is in CLI simulation mode..."
|
|
9
|
+
* User: "<cmd>cut -c 1-N < conversation.txt</cmd>"
|
|
10
|
+
* Assistant: <the full conversation log, N chars>
|
|
11
|
+
* User: "<cmd>cat conversation.txt</cmd>" (or cut -c N+1-)
|
|
12
|
+
* <model continues from where the cut output ended>
|
|
13
|
+
*
|
|
14
|
+
* Two continuation modes:
|
|
15
|
+
* - 'cat': model repeats full file then continues (reliable, caller strips log)
|
|
16
|
+
* - 'tail-cut': model outputs only new content (efficient, needs simulated stops)
|
|
17
|
+
*
|
|
18
|
+
* IMPORTANT: API-level stop sequences should NOT be used with pseudo-prefill.
|
|
19
|
+
* In 'cat' mode, the model repeats participant names from the log which would
|
|
20
|
+
* trigger stops prematurely. The caller should handle stop sequences post-facto
|
|
21
|
+
* after stripping the repeated log. The stop sequences returned in BuildResult
|
|
22
|
+
* are for the caller's post-facto detection, not for the API.
|
|
23
|
+
*
|
|
24
|
+
* Uses PassthroughParser and native API tools (same as NativeFormatter).
|
|
25
|
+
*/
|
|
26
|
+
import type { NormalizedMessage, ContentBlock, ToolCall, ToolResult } from '../types/index.js';
|
|
27
|
+
import type { PrefillFormatter, StreamParser, BuildOptions, BuildResult, FormatterConfig } from './types.js';
|
|
28
|
+
export interface PseudoPrefillFormatterConfig extends FormatterConfig {
|
|
29
|
+
/**
|
|
30
|
+
* Filename used in the CLI simulation commands.
|
|
31
|
+
* Default: 'conversation.txt'
|
|
32
|
+
*/
|
|
33
|
+
filename?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Continuation mode:
|
|
36
|
+
* - 'cat': `cat filename` — model repeats full file then continues.
|
|
37
|
+
* More reliable but uses more output tokens. Caller must strip the
|
|
38
|
+
* repeated conversation log from the response.
|
|
39
|
+
* - 'tail-cut': `cut -c N+1- < filename` — model outputs only new content.
|
|
40
|
+
* More efficient but may be less reliable. Caller needs simulated stop
|
|
41
|
+
* sequences (only after \n\n, not at position 0).
|
|
42
|
+
* Default: 'cat'
|
|
43
|
+
*/
|
|
44
|
+
continuationMode?: 'cat' | 'tail-cut';
|
|
45
|
+
/**
|
|
46
|
+
* Maximum participants to include in stop sequences.
|
|
47
|
+
* Default: 10
|
|
48
|
+
*/
|
|
49
|
+
maxParticipantsForStop?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Message delimiter between participant entries.
|
|
52
|
+
* Default: '' (none, just newlines)
|
|
53
|
+
*/
|
|
54
|
+
messageDelimiter?: string;
|
|
55
|
+
}
|
|
56
|
+
export declare class PseudoPrefillFormatter implements PrefillFormatter {
|
|
57
|
+
readonly name = "pseudo-prefill";
|
|
58
|
+
readonly usesPrefill = false;
|
|
59
|
+
private config;
|
|
60
|
+
constructor(config?: PseudoPrefillFormatterConfig);
|
|
61
|
+
buildMessages(messages: NormalizedMessage[], options: BuildOptions): BuildResult;
|
|
62
|
+
formatToolResults(results: ToolResult[]): string;
|
|
63
|
+
createStreamParser(): StreamParser;
|
|
64
|
+
parseToolCalls(_content: string): ToolCall[];
|
|
65
|
+
hasToolUse(_content: string): boolean;
|
|
66
|
+
parseContentBlocks(content: string): ContentBlock[];
|
|
67
|
+
private extractContent;
|
|
68
|
+
private buildStopSequences;
|
|
69
|
+
private convertToNativeTools;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=pseudo-prefill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pseudo-prefill.d.ts","sourceRoot":"","sources":["../../src/formatters/pseudo-prefill.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,YAAY,EAEZ,QAAQ,EACR,UAAU,EACX,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,eAAe,EAMhB,MAAM,YAAY,CAAC;AAMpB,MAAM,WAAW,4BAA6B,SAAQ,eAAe;IACnE;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;;;;OASG;IACH,gBAAgB,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC;IAEtC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAqGD,qBAAa,sBAAuB,YAAW,gBAAgB;IAC7D,QAAQ,CAAC,IAAI,oBAAoB;IACjC,QAAQ,CAAC,WAAW,SAAS;IAE7B,OAAO,CAAC,MAAM,CAAyC;gBAE3C,MAAM,GAAE,4BAAiC;IAerD,aAAa,CAAC,QAAQ,EAAE,iBAAiB,EAAE,EAAE,OAAO,EAAE,YAAY,GAAG,WAAW;IA+NhF,iBAAiB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM;IAahD,kBAAkB,IAAI,YAAY;IAIlC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,EAAE;IAK5C,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAKrC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE;IAWnD,OAAO,CAAC,cAAc;IAqCtB,OAAO,CAAC,kBAAkB;IA8B1B,OAAO,CAAC,oBAAoB;CAO7B"}
|
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pseudo-Prefill Formatter
|
|
3
|
+
*
|
|
4
|
+
* Recovers prefill-like behavior for models that don't support native
|
|
5
|
+
* assistant message prefill (e.g., Sonnet 4.6, Opus 4.6). Uses a CLI
|
|
6
|
+
* simulation framing trick:
|
|
7
|
+
*
|
|
8
|
+
* System: "The assistant is in CLI simulation mode..."
|
|
9
|
+
* User: "<cmd>cut -c 1-N < conversation.txt</cmd>"
|
|
10
|
+
* Assistant: <the full conversation log, N chars>
|
|
11
|
+
* User: "<cmd>cat conversation.txt</cmd>" (or cut -c N+1-)
|
|
12
|
+
* <model continues from where the cut output ended>
|
|
13
|
+
*
|
|
14
|
+
* Two continuation modes:
|
|
15
|
+
* - 'cat': model repeats full file then continues (reliable, caller strips log)
|
|
16
|
+
* - 'tail-cut': model outputs only new content (efficient, needs simulated stops)
|
|
17
|
+
*
|
|
18
|
+
* IMPORTANT: API-level stop sequences should NOT be used with pseudo-prefill.
|
|
19
|
+
* In 'cat' mode, the model repeats participant names from the log which would
|
|
20
|
+
* trigger stops prematurely. The caller should handle stop sequences post-facto
|
|
21
|
+
* after stripping the repeated log. The stop sequences returned in BuildResult
|
|
22
|
+
* are for the caller's post-facto detection, not for the API.
|
|
23
|
+
*
|
|
24
|
+
* Uses PassthroughParser and native API tools (same as NativeFormatter).
|
|
25
|
+
*/
|
|
26
|
+
// ============================================================================
|
|
27
|
+
// Pass-through Stream Parser (same as NativeFormatter)
|
|
28
|
+
// ============================================================================
|
|
29
|
+
class PassthroughParser {
|
|
30
|
+
accumulated = '';
|
|
31
|
+
blockIndex = 0;
|
|
32
|
+
blockStarted = false;
|
|
33
|
+
processChunk(chunk) {
|
|
34
|
+
this.accumulated += chunk;
|
|
35
|
+
const meta = {
|
|
36
|
+
type: 'text',
|
|
37
|
+
visible: true,
|
|
38
|
+
blockIndex: this.blockIndex,
|
|
39
|
+
};
|
|
40
|
+
const emissions = [];
|
|
41
|
+
const blockEvents = [];
|
|
42
|
+
if (!this.blockStarted) {
|
|
43
|
+
const startEvent = {
|
|
44
|
+
event: 'block_start',
|
|
45
|
+
index: this.blockIndex,
|
|
46
|
+
block: { type: 'text' },
|
|
47
|
+
};
|
|
48
|
+
emissions.push({ kind: 'blockEvent', event: startEvent });
|
|
49
|
+
blockEvents.push(startEvent);
|
|
50
|
+
this.blockStarted = true;
|
|
51
|
+
}
|
|
52
|
+
emissions.push({ kind: 'content', text: chunk, meta });
|
|
53
|
+
return { emissions, content: [{ text: chunk, meta }], blockEvents };
|
|
54
|
+
}
|
|
55
|
+
flush() {
|
|
56
|
+
const emissions = [];
|
|
57
|
+
const blockEvents = [];
|
|
58
|
+
if (this.blockStarted) {
|
|
59
|
+
const completeEvent = {
|
|
60
|
+
event: 'block_complete',
|
|
61
|
+
index: this.blockIndex,
|
|
62
|
+
block: { type: 'text', content: this.accumulated },
|
|
63
|
+
};
|
|
64
|
+
emissions.push({ kind: 'blockEvent', event: completeEvent });
|
|
65
|
+
blockEvents.push(completeEvent);
|
|
66
|
+
this.blockStarted = false;
|
|
67
|
+
}
|
|
68
|
+
return { emissions, content: [], blockEvents };
|
|
69
|
+
}
|
|
70
|
+
getAccumulated() {
|
|
71
|
+
return this.accumulated;
|
|
72
|
+
}
|
|
73
|
+
reset() {
|
|
74
|
+
this.accumulated = '';
|
|
75
|
+
this.blockIndex = 0;
|
|
76
|
+
this.blockStarted = false;
|
|
77
|
+
}
|
|
78
|
+
push(content) {
|
|
79
|
+
this.accumulated += content;
|
|
80
|
+
}
|
|
81
|
+
getCurrentBlockType() {
|
|
82
|
+
return 'text';
|
|
83
|
+
}
|
|
84
|
+
getBlockIndex() {
|
|
85
|
+
return this.blockIndex;
|
|
86
|
+
}
|
|
87
|
+
incrementBlockIndex() {
|
|
88
|
+
this.blockIndex++;
|
|
89
|
+
}
|
|
90
|
+
isInsideBlock() {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
getDepths() {
|
|
94
|
+
return { functionCalls: 0, functionResults: 0, thinking: 0 };
|
|
95
|
+
}
|
|
96
|
+
resetForNewIteration() {
|
|
97
|
+
// No special reset needed for pass-through mode
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// ============================================================================
|
|
101
|
+
// Pseudo-Prefill Formatter
|
|
102
|
+
// ============================================================================
|
|
103
|
+
const CLI_DIRECTIVE = 'The assistant is in CLI simulation mode, and responds to the user\'s CLI commands only with the output of the command.';
|
|
104
|
+
export class PseudoPrefillFormatter {
|
|
105
|
+
name = 'pseudo-prefill';
|
|
106
|
+
usesPrefill = false;
|
|
107
|
+
config;
|
|
108
|
+
constructor(config = {}) {
|
|
109
|
+
this.config = {
|
|
110
|
+
filename: config.filename ?? 'conversation.txt',
|
|
111
|
+
continuationMode: config.continuationMode ?? 'cat',
|
|
112
|
+
maxParticipantsForStop: config.maxParticipantsForStop ?? 10,
|
|
113
|
+
messageDelimiter: config.messageDelimiter ?? '',
|
|
114
|
+
unsupportedMedia: config.unsupportedMedia ?? 'strip',
|
|
115
|
+
warnOnStrip: config.warnOnStrip ?? true,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
// ==========================================================================
|
|
119
|
+
// REQUEST BUILDING
|
|
120
|
+
// ==========================================================================
|
|
121
|
+
buildMessages(messages, options) {
|
|
122
|
+
const { assistantParticipant, tools, systemPrompt, promptCaching = false, cacheTtl, contextPrefix, hasCacheMarker, additionalStopSequences, } = options;
|
|
123
|
+
// Build cache_control object
|
|
124
|
+
const cacheControl = { type: 'ephemeral' };
|
|
125
|
+
if (cacheTtl) {
|
|
126
|
+
cacheControl.ttl = cacheTtl;
|
|
127
|
+
}
|
|
128
|
+
// 1. Build system content: user's system prompt + CLI directive
|
|
129
|
+
let systemText = typeof systemPrompt === 'string' ? systemPrompt : '';
|
|
130
|
+
if (Array.isArray(systemPrompt)) {
|
|
131
|
+
systemText = systemPrompt
|
|
132
|
+
.filter((b) => b.type === 'text')
|
|
133
|
+
.map(b => b.text)
|
|
134
|
+
.join('\n');
|
|
135
|
+
}
|
|
136
|
+
systemText = systemText
|
|
137
|
+
? `${systemText}\n\n${CLI_DIRECTIVE}`
|
|
138
|
+
: CLI_DIRECTIVE;
|
|
139
|
+
let systemContent;
|
|
140
|
+
const systemBlock = { type: 'text', text: systemText };
|
|
141
|
+
if (promptCaching) {
|
|
142
|
+
systemBlock.cache_control = cacheControl;
|
|
143
|
+
}
|
|
144
|
+
systemContent = [systemBlock];
|
|
145
|
+
// 2. Build the conversation log, handling images like AnthropicXmlFormatter:
|
|
146
|
+
// When a message has images, flush the accumulated log as an assistant turn,
|
|
147
|
+
// add the image as a user turn, then continue accumulating.
|
|
148
|
+
let currentLog = [];
|
|
149
|
+
let cacheMarkersApplied = promptCaching ? 1 : 0; // system block
|
|
150
|
+
const joiner = this.config.messageDelimiter ? '' : '\n';
|
|
151
|
+
const filename = this.config.filename;
|
|
152
|
+
// Track image flushes — these become user turns between cut result and cat
|
|
153
|
+
const imageTurns = [];
|
|
154
|
+
const logSegments = [];
|
|
155
|
+
// Context prefix (simulacrum seeding) goes first in the log
|
|
156
|
+
if (contextPrefix) {
|
|
157
|
+
currentLog.push(contextPrefix);
|
|
158
|
+
}
|
|
159
|
+
// Serialize messages
|
|
160
|
+
let lastParticipant = '';
|
|
161
|
+
for (let i = 0; i < messages.length; i++) {
|
|
162
|
+
const message = messages[i];
|
|
163
|
+
if (!message)
|
|
164
|
+
continue;
|
|
165
|
+
const { text, images, hasUnsupportedMedia } = this.extractContent(message.content, message.participant);
|
|
166
|
+
const hasImages = images.length > 0;
|
|
167
|
+
const isEmpty = !text.trim() && !hasImages;
|
|
168
|
+
if (hasUnsupportedMedia) {
|
|
169
|
+
if (this.config.unsupportedMedia === 'error') {
|
|
170
|
+
throw new Error(`PseudoPrefillFormatter does not support media in message from ${message.participant}. Configure unsupportedMedia: 'strip' to ignore.`);
|
|
171
|
+
}
|
|
172
|
+
else if (this.config.warnOnStrip) {
|
|
173
|
+
console.warn(`[PseudoPrefillFormatter] Stripped unsupported media from message`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (isEmpty)
|
|
177
|
+
continue;
|
|
178
|
+
// If message has images, flush current log and add image as user turn
|
|
179
|
+
if (hasImages) {
|
|
180
|
+
if (currentLog.length > 0) {
|
|
181
|
+
logSegments.push({ text: currentLog.join(joiner) });
|
|
182
|
+
currentLog = [];
|
|
183
|
+
}
|
|
184
|
+
const userContent = [];
|
|
185
|
+
if (text) {
|
|
186
|
+
userContent.push({ type: 'text', text: `${message.participant}: ${text}` });
|
|
187
|
+
}
|
|
188
|
+
userContent.push(...images);
|
|
189
|
+
imageTurns.push({ role: 'user', content: userContent });
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
// Check cache breakpoint — flush segment WITH this message
|
|
193
|
+
if (message.cacheBreakpoint && promptCaching) {
|
|
194
|
+
currentLog.push(`${message.participant}: ${text}${this.config.messageDelimiter}`);
|
|
195
|
+
logSegments.push({ text: currentLog.join(joiner), cacheBreakpoint: true });
|
|
196
|
+
currentLog = [];
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
// hasCacheMarker: cache boundary BEFORE this message
|
|
200
|
+
if (hasCacheMarker && hasCacheMarker(message, i) && promptCaching && currentLog.length > 0) {
|
|
201
|
+
logSegments.push({ text: currentLog.join(joiner), cacheBreakpoint: true });
|
|
202
|
+
currentLog = [];
|
|
203
|
+
}
|
|
204
|
+
// Same participant as last message — merge without repeating name prefix
|
|
205
|
+
if (message.participant === lastParticipant && lastParticipant !== '') {
|
|
206
|
+
const lastEntry = currentLog[currentLog.length - 1];
|
|
207
|
+
if (lastEntry) {
|
|
208
|
+
currentLog[currentLog.length - 1] = lastEntry.trimEnd() + ' ' + text.trimStart() + '\n\n';
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
currentLog.push(`${message.participant}: ${text}${this.config.messageDelimiter}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
currentLog.push(`${message.participant}: ${text}${this.config.messageDelimiter}`);
|
|
216
|
+
}
|
|
217
|
+
lastParticipant = message.participant;
|
|
218
|
+
}
|
|
219
|
+
// Add the assistant participant turn prefix at the end
|
|
220
|
+
currentLog.push(`${assistantParticipant}:`);
|
|
221
|
+
logSegments.push({ text: currentLog.join(joiner) });
|
|
222
|
+
// Combine all log segments into the full conversation log for the cut char count
|
|
223
|
+
const fullLog = logSegments.map(s => s.text).join(joiner);
|
|
224
|
+
const charCount = fullLog.length;
|
|
225
|
+
// 3. Build the message structure
|
|
226
|
+
const providerMessages = [];
|
|
227
|
+
// User: cut command (request first N chars, wrapped in <cmd> tags)
|
|
228
|
+
providerMessages.push({
|
|
229
|
+
role: 'user',
|
|
230
|
+
content: `<cmd>cut -c 1-${charCount} < ${filename}</cmd>`,
|
|
231
|
+
});
|
|
232
|
+
// Assistant: the conversation log
|
|
233
|
+
// If there are multiple segments with cache breakpoints, split into
|
|
234
|
+
// multiple assistant content blocks. Otherwise, single block.
|
|
235
|
+
if (logSegments.length === 1 || !promptCaching) {
|
|
236
|
+
const logBlock = { type: 'text', text: fullLog };
|
|
237
|
+
if (promptCaching) {
|
|
238
|
+
logBlock.cache_control = cacheControl;
|
|
239
|
+
cacheMarkersApplied++;
|
|
240
|
+
}
|
|
241
|
+
providerMessages.push({
|
|
242
|
+
role: 'assistant',
|
|
243
|
+
content: [logBlock],
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
// Multiple segments with cache breakpoints
|
|
248
|
+
const contentBlocks = [];
|
|
249
|
+
for (const segment of logSegments) {
|
|
250
|
+
const block = { type: 'text', text: segment.text };
|
|
251
|
+
if (segment.cacheBreakpoint) {
|
|
252
|
+
block.cache_control = cacheControl;
|
|
253
|
+
cacheMarkersApplied++;
|
|
254
|
+
}
|
|
255
|
+
contentBlocks.push(block);
|
|
256
|
+
}
|
|
257
|
+
// Ensure last block is cached too
|
|
258
|
+
const lastBlock = contentBlocks[contentBlocks.length - 1];
|
|
259
|
+
if (!lastBlock.cache_control && promptCaching) {
|
|
260
|
+
lastBlock.cache_control = cacheControl;
|
|
261
|
+
cacheMarkersApplied++;
|
|
262
|
+
}
|
|
263
|
+
providerMessages.push({
|
|
264
|
+
role: 'assistant',
|
|
265
|
+
content: contentBlocks,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
// Insert image turns between the assistant log and the cat command
|
|
269
|
+
// These are user turns containing image content
|
|
270
|
+
for (const imageTurn of imageTurns) {
|
|
271
|
+
// Need a brief assistant acknowledgment to maintain alternating turns
|
|
272
|
+
providerMessages.push({
|
|
273
|
+
role: 'assistant',
|
|
274
|
+
content: '[image received]',
|
|
275
|
+
});
|
|
276
|
+
providerMessages.push(imageTurn);
|
|
277
|
+
}
|
|
278
|
+
// User: continuation command
|
|
279
|
+
// - 'cat': model repeats full file (caller strips repeated log from response)
|
|
280
|
+
// - 'tail-cut': model outputs only chars after the cut point
|
|
281
|
+
const continuationCmd = this.config.continuationMode === 'tail-cut'
|
|
282
|
+
? `<cmd>cut -c ${charCount + 1}- < ${filename}</cmd>`
|
|
283
|
+
: `<cmd>cat ${filename}</cmd>`;
|
|
284
|
+
providerMessages.push({
|
|
285
|
+
role: 'user',
|
|
286
|
+
content: continuationCmd,
|
|
287
|
+
});
|
|
288
|
+
// 4. Build stop sequences from participant names
|
|
289
|
+
// NOTE: For pseudo-prefill, API-level stop sequences are problematic because
|
|
290
|
+
// in 'cat' mode the model repeats the conversation log (which contains
|
|
291
|
+
// participant names that would trigger stops prematurely).
|
|
292
|
+
// The caller should handle stop sequences post-facto after stripping the log.
|
|
293
|
+
// We still return them here for the caller to use in post-facto detection.
|
|
294
|
+
const stopSequences = this.buildStopSequences(messages, assistantParticipant, options);
|
|
295
|
+
// 5. Native tools
|
|
296
|
+
const nativeTools = tools?.length ? this.convertToNativeTools(tools) : undefined;
|
|
297
|
+
return {
|
|
298
|
+
messages: providerMessages,
|
|
299
|
+
systemContent,
|
|
300
|
+
// No assistantPrefill — model generates a new assistant turn after continuation command
|
|
301
|
+
assistantPrefill: undefined,
|
|
302
|
+
stopSequences,
|
|
303
|
+
nativeTools,
|
|
304
|
+
cacheMarkersApplied,
|
|
305
|
+
// Expose log and mode so callers can strip the repeated log (cat mode)
|
|
306
|
+
// and apply post-facto stop sequences appropriately
|
|
307
|
+
metadata: {
|
|
308
|
+
conversationLog: fullLog,
|
|
309
|
+
conversationLogLength: charCount,
|
|
310
|
+
continuationMode: this.config.continuationMode,
|
|
311
|
+
assistantParticipant: assistantParticipant,
|
|
312
|
+
},
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
formatToolResults(results) {
|
|
316
|
+
// Native mode uses API tool_result blocks
|
|
317
|
+
return JSON.stringify(results.map(r => ({
|
|
318
|
+
tool_use_id: r.toolUseId,
|
|
319
|
+
content: r.content,
|
|
320
|
+
is_error: r.isError,
|
|
321
|
+
})));
|
|
322
|
+
}
|
|
323
|
+
// ==========================================================================
|
|
324
|
+
// RESPONSE PARSING
|
|
325
|
+
// ==========================================================================
|
|
326
|
+
createStreamParser() {
|
|
327
|
+
return new PassthroughParser();
|
|
328
|
+
}
|
|
329
|
+
parseToolCalls(_content) {
|
|
330
|
+
// Native mode gets tool calls from API response
|
|
331
|
+
return [];
|
|
332
|
+
}
|
|
333
|
+
hasToolUse(_content) {
|
|
334
|
+
// Native mode determines tool use from API stop_reason
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
parseContentBlocks(content) {
|
|
338
|
+
if (!content.trim()) {
|
|
339
|
+
return [];
|
|
340
|
+
}
|
|
341
|
+
return [{ type: 'text', text: content }];
|
|
342
|
+
}
|
|
343
|
+
// ==========================================================================
|
|
344
|
+
// PRIVATE HELPERS
|
|
345
|
+
// ==========================================================================
|
|
346
|
+
extractContent(content, participant) {
|
|
347
|
+
const parts = [];
|
|
348
|
+
const images = [];
|
|
349
|
+
let hasUnsupportedMedia = false;
|
|
350
|
+
for (const block of content) {
|
|
351
|
+
if (block.type === 'text') {
|
|
352
|
+
parts.push(block.text);
|
|
353
|
+
}
|
|
354
|
+
else if (block.type === 'image') {
|
|
355
|
+
if (block.source.type === 'base64') {
|
|
356
|
+
images.push({
|
|
357
|
+
type: 'image',
|
|
358
|
+
source: {
|
|
359
|
+
type: 'base64',
|
|
360
|
+
media_type: block.source.mediaType,
|
|
361
|
+
data: block.source.data,
|
|
362
|
+
},
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
else if (block.type === 'tool_use') {
|
|
367
|
+
parts.push(`${participant}>[${block.name}]: ${JSON.stringify(block.input)}`);
|
|
368
|
+
}
|
|
369
|
+
else if (block.type === 'tool_result') {
|
|
370
|
+
const resultText = typeof block.content === 'string'
|
|
371
|
+
? block.content
|
|
372
|
+
: JSON.stringify(block.content);
|
|
373
|
+
parts.push(`${participant}<[tool_result]: ${resultText}`);
|
|
374
|
+
}
|
|
375
|
+
else if (block.type === 'document' || block.type === 'audio') {
|
|
376
|
+
hasUnsupportedMedia = true;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return { text: parts.join('\n'), images, hasUnsupportedMedia };
|
|
380
|
+
}
|
|
381
|
+
buildStopSequences(messages, assistantName, options) {
|
|
382
|
+
const sequences = [];
|
|
383
|
+
const maxParticipants = options.maxParticipantsForStop ?? this.config.maxParticipantsForStop;
|
|
384
|
+
// Collect unique participants (excluding assistant) from recent messages
|
|
385
|
+
const participants = new Set();
|
|
386
|
+
for (let i = messages.length - 1; i >= 0 && participants.size < maxParticipants; i--) {
|
|
387
|
+
const message = messages[i];
|
|
388
|
+
if (message && message.participant !== assistantName) {
|
|
389
|
+
participants.add(message.participant);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
// Participant-based stops (same format as AnthropicXmlFormatter)
|
|
393
|
+
for (const participant of participants) {
|
|
394
|
+
sequences.push(`\n${participant}:`);
|
|
395
|
+
}
|
|
396
|
+
// Add any additional stop sequences from options
|
|
397
|
+
if (options.additionalStopSequences?.length) {
|
|
398
|
+
sequences.push(...options.additionalStopSequences);
|
|
399
|
+
}
|
|
400
|
+
return sequences;
|
|
401
|
+
}
|
|
402
|
+
convertToNativeTools(tools) {
|
|
403
|
+
return tools.map(tool => ({
|
|
404
|
+
name: tool.name,
|
|
405
|
+
description: tool.description,
|
|
406
|
+
input_schema: tool.inputSchema,
|
|
407
|
+
}));
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
//# sourceMappingURL=pseudo-prefill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pseudo-prefill.js","sourceRoot":"","sources":["../../src/formatters/pseudo-prefill.ts"],"names":[],"mappings":"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"}
|
|
@@ -65,6 +65,10 @@ export interface BuildResult {
|
|
|
65
65
|
nativeTools?: unknown[];
|
|
66
66
|
/** Number of cache control markers applied (for Anthropic prompt caching) */
|
|
67
67
|
cacheMarkersApplied?: number;
|
|
68
|
+
/** Formatter-specific metadata for callers.
|
|
69
|
+
* e.g., pseudo-prefill includes conversationLog and continuationMode
|
|
70
|
+
* so the caller can strip the repeated log from 'cat' mode responses. */
|
|
71
|
+
metadata?: Record<string, unknown>;
|
|
68
72
|
}
|
|
69
73
|
export interface ProviderMessage {
|
|
70
74
|
role: 'user' | 'assistant';
|
package/dist/membrane.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"membrane.d.ts","sourceRoot":"","sources":["../src/membrane.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EAEf,eAAe,EAEf,cAAc,EACd,aAAa,EACb,eAAe,EAYhB,MAAM,kBAAkB,CAAC;AAmB1B,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EAGtB,MAAM,4BAA4B,CAAC;AAWpC,qBAAa,QAAQ;IACnB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,QAAQ,CAAC,CAAgB;IACjC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,SAAS,CAAmB;gBAGlC,OAAO,EAAE,eAAe,EACxB,MAAM,GAAE,cAAmB;IAc7B;;OAEG;IACG,QAAQ,CACZ,OAAO,EAAE,iBAAiB,EAC1B,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,kBAAkB,CAAC;IA4E9B;;;;;;;;;;;;;;;;;OAiBG;IACG,MAAM,CACV,OAAO,EAAE,iBAAiB,EAC1B,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,kBAAkB,GAAG,eAAe,CAAC;IA+BhD;;OAEG;IACH,OAAO,CAAC,eAAe;IAsBvB;;;;;;OAMG;YACW,kBAAkB;IAsdhC;;OAEG;YACW,qBAAqB;IAuOnC;;OAEG;IACH,OAAO,CAAC,sBAAsB;
|
|
1
|
+
{"version":3,"file":"membrane.d.ts","sourceRoot":"","sources":["../src/membrane.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EAEf,eAAe,EAEf,cAAc,EACd,aAAa,EACb,eAAe,EAYhB,MAAM,kBAAkB,CAAC;AAmB1B,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EAGtB,MAAM,4BAA4B,CAAC;AAWpC,qBAAa,QAAQ;IACnB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,QAAQ,CAAC,CAAgB;IACjC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,SAAS,CAAmB;gBAGlC,OAAO,EAAE,eAAe,EACxB,MAAM,GAAE,cAAmB;IAc7B;;OAEG;IACG,QAAQ,CACZ,OAAO,EAAE,iBAAiB,EAC1B,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,kBAAkB,CAAC;IA4E9B;;;;;;;;;;;;;;;;;OAiBG;IACG,MAAM,CACV,OAAO,EAAE,iBAAiB,EAC1B,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,kBAAkB,GAAG,eAAe,CAAC;IA+BhD;;OAEG;IACH,OAAO,CAAC,eAAe;IAsBvB;;;;;;OAMG;YACW,kBAAkB;IAsdhC;;OAEG;YACW,qBAAqB;IAuOnC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA0H9B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA2C5B;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAc7B;;OAEG;IACH,OAAO,CAAC,gBAAgB;YA+CV,UAAU;IAQxB,OAAO,CAAC,wBAAwB;IA2ChC;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,kCAAkC;IAiD1C,OAAO,CAAC,iBAAiB;IAkIzB,OAAO,CAAC,kBAAkB;IAkF1B,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,sBAAsB;IAO9B,OAAO,CAAC,cAAc;IAItB,qFAAqF;IACrF,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,mBAAmB;IAM3B,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,KAAK;IAcb;;OAEG;IACH,OAAO,CAAC,YAAY;IAcpB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA4B5B;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,cAAc,CACZ,OAAO,EAAE,iBAAiB,EAC1B,OAAO,GAAE,qBAA0B,GAClC,cAAc;IAWjB;;OAEG;YACW,mBAAmB;IA6bjC;;OAEG;YACW,sBAAsB;CAgOrC"}
|
package/dist/membrane.js
CHANGED
|
@@ -722,9 +722,14 @@ export class Membrane {
|
|
|
722
722
|
const role = isAssistant ? 'assistant' : 'user';
|
|
723
723
|
// Convert content blocks
|
|
724
724
|
const content = [];
|
|
725
|
+
const includeNamePrefix = !isAssistant;
|
|
725
726
|
for (const block of msg.content) {
|
|
726
727
|
if (block.type === 'text') {
|
|
727
|
-
|
|
728
|
+
let text = block.text;
|
|
729
|
+
if (includeNamePrefix && msg.participant) {
|
|
730
|
+
text = `${msg.participant}: ${text}`;
|
|
731
|
+
}
|
|
732
|
+
const textBlock = { type: 'text', text };
|
|
728
733
|
if (block.cache_control) {
|
|
729
734
|
textBlock.cache_control = block.cache_control;
|
|
730
735
|
}
|