@recombine-ai/engine 1.0.0-beta-2 → 1.0.0-beta-4
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/.github/workflows/linting.yml +2 -2
- package/.github/workflows/publish.yml +1 -2
- package/build/index.d.ts +2 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3 -2
- package/build/lib/bosun/action.d.ts.map +1 -1
- package/build/lib/bosun/action.js +1 -0
- package/build/lib/bosun/agent.d.ts +1 -4
- package/build/lib/bosun/agent.d.ts.map +1 -1
- package/build/lib/engine.d.ts +31 -0
- package/build/lib/engine.d.ts.map +1 -0
- package/build/lib/interfaces/adapter.d.ts +13 -0
- package/build/lib/interfaces/adapter.d.ts.map +1 -0
- package/build/lib/interfaces/conversation.d.ts +63 -0
- package/build/lib/interfaces/conversation.d.ts.map +1 -0
- package/build/lib/interfaces/engine.d.ts +65 -0
- package/build/lib/interfaces/engine.d.ts.map +1 -0
- package/build/lib/interfaces/engine.js +2 -0
- package/build/lib/interfaces/index.d.ts +8 -0
- package/build/lib/interfaces/index.d.ts.map +1 -0
- package/build/lib/interfaces/index.js +23 -0
- package/build/lib/{interfaces.d.ts → interfaces/other.d.ts} +1 -1
- package/build/lib/interfaces/other.d.ts.map +1 -0
- package/build/lib/interfaces/other.js +2 -0
- package/build/lib/interfaces/steps.d.ts +84 -0
- package/build/lib/interfaces/steps.d.ts.map +1 -0
- package/build/lib/interfaces/steps.js +2 -0
- package/build/lib/{stream/interfaces.d.ts → interfaces/stream.d.ts} +8 -22
- package/build/lib/interfaces/stream.d.ts.map +1 -0
- package/build/lib/interfaces/stream.js +2 -0
- package/build/lib/interfaces/workflow.d.ts +44 -0
- package/build/lib/interfaces/workflow.d.ts.map +1 -0
- package/build/lib/interfaces/workflow.js +2 -0
- package/build/lib/llm-adapters/mock.d.ts +1 -1
- package/build/lib/llm-adapters/mock.d.ts.map +1 -1
- package/build/lib/llm-adapters/openai-stream.d.ts +1 -1
- package/build/lib/llm-adapters/openai.d.ts +1 -1
- package/build/lib/llm-adapters/openai.d.ts.map +1 -1
- package/build/lib/stream/engine.d.ts +3 -0
- package/build/lib/stream/engine.d.ts.map +1 -0
- package/build/lib/stream/engine.js +174 -0
- package/build/lib/stream/index.d.ts +2 -2
- package/build/lib/stream/index.d.ts.map +1 -1
- package/build/lib/stream/index.js +2 -2
- package/build/lib/stream/token-transformers.d.ts +6 -0
- package/build/lib/stream/token-transformers.d.ts.map +1 -0
- package/build/lib/stream/token-transformers.js +62 -0
- package/changelog.md +1 -0
- package/package.json +1 -1
- package/build/lib/ai.d.ts +0 -286
- package/build/lib/ai.d.ts.map +0 -1
- package/build/lib/interfaces.d.ts.map +0 -1
- package/build/lib/stream/ai.d.ts +0 -3
- package/build/lib/stream/ai.d.ts.map +0 -1
- package/build/lib/stream/ai.js +0 -224
- package/build/lib/stream/filter.d.ts +0 -6
- package/build/lib/stream/filter.d.ts.map +0 -1
- package/build/lib/stream/filter.js +0 -20
- package/build/lib/stream/interfaces.d.ts.map +0 -1
- /package/build/lib/{ai.js → engine.js} +0 -0
- /package/build/lib/{interfaces.js → interfaces/adapter.js} +0 -0
- /package/build/lib/{stream/interfaces.js → interfaces/conversation.js} +0 -0
package/build/lib/stream/ai.js
DELETED
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.createAIStreamEngine = createAIStreamEngine;
|
|
7
|
-
// cspell:words TTFT lstrip
|
|
8
|
-
const nunjucks_1 = __importDefault(require("nunjucks"));
|
|
9
|
-
const bosun_1 = require("../bosun");
|
|
10
|
-
const filter_1 = require("./filter");
|
|
11
|
-
const step_registry_1 = require("../bosun/step-registry");
|
|
12
|
-
function createAIStreamEngine(cfg) {
|
|
13
|
-
function createWorkflow({ name, prompt, model, filter = filter_1.defaultFilter, onError, }) {
|
|
14
|
-
const logger = cfg.logger || console;
|
|
15
|
-
logger.debug('streamAiEngine.createWorkflow');
|
|
16
|
-
const stepTracer = cfg.stepTracer || (0, bosun_1.createStubStepTracer)(logger);
|
|
17
|
-
cfg.stepRegistry?.addStep({
|
|
18
|
-
type: 'streaming-response',
|
|
19
|
-
name,
|
|
20
|
-
prompt: (0, step_registry_1.stdPrompt)(prompt),
|
|
21
|
-
});
|
|
22
|
-
async function run(messages, ctx) {
|
|
23
|
-
let streamCancelled = false;
|
|
24
|
-
return new ReadableStream({
|
|
25
|
-
cancel: (reason) => {
|
|
26
|
-
logger.debug(`streamingWorkflow.run cancelled: ${reason}`);
|
|
27
|
-
streamCancelled = true;
|
|
28
|
-
},
|
|
29
|
-
start: async (controller) => {
|
|
30
|
-
try {
|
|
31
|
-
const stream = await generateResponseStream(messages, ctx);
|
|
32
|
-
for await (const chunk of stream) {
|
|
33
|
-
if (streamCancelled)
|
|
34
|
-
return;
|
|
35
|
-
controller.enqueue(chunk);
|
|
36
|
-
}
|
|
37
|
-
if (streamCancelled)
|
|
38
|
-
return;
|
|
39
|
-
controller.close();
|
|
40
|
-
}
|
|
41
|
-
catch (e) {
|
|
42
|
-
if (streamCancelled) {
|
|
43
|
-
logger.debug('streamingWorkflow.run will not propagate error due to stream cancellation', e);
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
controller.error(e);
|
|
47
|
-
await onError(e, ctx);
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
async function generateResponseStream(messages, ctx) {
|
|
53
|
-
const runId = crypto.randomUUID();
|
|
54
|
-
logger.debug(`streamingWorkflow.run runId: ${runId}`);
|
|
55
|
-
const startTime = performance.now();
|
|
56
|
-
const transcript = createTranscript(logger, messages);
|
|
57
|
-
let currentFilter = null;
|
|
58
|
-
let filteredTokens = [];
|
|
59
|
-
// Create step trace for telescope
|
|
60
|
-
const mainStepTrace = {
|
|
61
|
-
workflowId: name,
|
|
62
|
-
workflowRunId: runId,
|
|
63
|
-
name: name,
|
|
64
|
-
model: String(model.getOptions()),
|
|
65
|
-
createdAt: Date.now(),
|
|
66
|
-
response: '',
|
|
67
|
-
};
|
|
68
|
-
const renderedPrompt = await renderPrompt(prompt, ctx);
|
|
69
|
-
const stringifiedConversation = transcript.toString();
|
|
70
|
-
mainStepTrace.renderedPrompt = renderedPrompt;
|
|
71
|
-
mainStepTrace.stringifiedConversation = stringifiedConversation;
|
|
72
|
-
let mainStepStream;
|
|
73
|
-
try {
|
|
74
|
-
mainStepStream = await model.generateStream(renderedPrompt, stringifiedConversation);
|
|
75
|
-
}
|
|
76
|
-
catch (error) {
|
|
77
|
-
logger.error('AI Engine Stream: LLM error', { error });
|
|
78
|
-
if (mainStepTrace) {
|
|
79
|
-
mainStepTrace.error = error instanceof Error ? error : new Error(String(error));
|
|
80
|
-
cfg.stepTracer?.addStepTrace(mainStepTrace);
|
|
81
|
-
await cfg.stepTracer?.flush();
|
|
82
|
-
}
|
|
83
|
-
throw error;
|
|
84
|
-
}
|
|
85
|
-
logger.debug(`[MARK] stream created: ${(performance.now() - startTime).toFixed(2)}ms`);
|
|
86
|
-
let measureTtft = true;
|
|
87
|
-
let streamCancelled = false;
|
|
88
|
-
return new ReadableStream({
|
|
89
|
-
cancel: (reason) => {
|
|
90
|
-
logger.debug(`streamingWorkflow.generateResponseStream cancelled: ${reason}`);
|
|
91
|
-
streamCancelled = true;
|
|
92
|
-
},
|
|
93
|
-
async start(controller) {
|
|
94
|
-
logger.debug('streamingWorkflow.run: starting main stream');
|
|
95
|
-
for await (const chunk of mainStepStream) {
|
|
96
|
-
if (measureTtft) {
|
|
97
|
-
logger.debug(`[MARK] TTFT: ${(performance.now() - startTime).toFixed(2)}ms`);
|
|
98
|
-
measureTtft = false;
|
|
99
|
-
}
|
|
100
|
-
const delta = chunk;
|
|
101
|
-
if (!delta) {
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
let tokensToRelease = [];
|
|
105
|
-
if (currentFilter) {
|
|
106
|
-
filteredTokens.push(delta);
|
|
107
|
-
const filterResult = currentFilter.onNewToken(transcript, filteredTokens);
|
|
108
|
-
if (filterResult.action === 'RELEASE_TOKENS') {
|
|
109
|
-
logger.debug('streamingWorkflow.run: programmatic filter releasing tokens: ', JSON.stringify(filterResult.tokens));
|
|
110
|
-
tokensToRelease = filterResult.tokens;
|
|
111
|
-
currentFilter = null;
|
|
112
|
-
filteredTokens = [];
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
else if (filter?.shouldStartFiltering(transcript, delta)) {
|
|
116
|
-
filteredTokens = [delta];
|
|
117
|
-
currentFilter = filter;
|
|
118
|
-
logger.debug('streamingWorkflow.run: programmatic filter is applied on token: ', delta);
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
tokensToRelease = [delta];
|
|
122
|
-
}
|
|
123
|
-
releaseMainStreamTokens(tokensToRelease);
|
|
124
|
-
}
|
|
125
|
-
if (currentFilter) {
|
|
126
|
-
// stream has ended, but the filter still has some tokens to release
|
|
127
|
-
releaseMainStreamTokens(currentFilter.onStreamEnd(transcript, filteredTokens).tokensToRelease);
|
|
128
|
-
currentFilter = null;
|
|
129
|
-
filteredTokens = [];
|
|
130
|
-
}
|
|
131
|
-
function releaseMainStreamTokens(tokens) {
|
|
132
|
-
for (const token of tokens) {
|
|
133
|
-
if (streamCancelled) {
|
|
134
|
-
break;
|
|
135
|
-
}
|
|
136
|
-
transcript.responseChunks.push({ role: 'agent', delta: token });
|
|
137
|
-
controller.enqueue({ role: 'agent', delta: token });
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
logger.debug('streamingWorkflow.run: markMainResponseFinished', {
|
|
141
|
-
elapsedMs: (performance.now() - startTime).toFixed(2),
|
|
142
|
-
});
|
|
143
|
-
transcript.markMainResponseFinished();
|
|
144
|
-
// Add step trace and flush to telescope
|
|
145
|
-
cfg.stepTracer?.addStepTrace(mainStepTrace);
|
|
146
|
-
await cfg.stepTracer?.flush();
|
|
147
|
-
if (!streamCancelled) {
|
|
148
|
-
controller.close();
|
|
149
|
-
}
|
|
150
|
-
await stepTracer.flush();
|
|
151
|
-
},
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
async function renderPrompt(prompt, context) {
|
|
155
|
-
logger.debug('Streaming AI, CONTEXT:', context);
|
|
156
|
-
const template = typeof prompt === 'string' ? prompt : await prompt.content();
|
|
157
|
-
if (context) {
|
|
158
|
-
logger.debug('Loaded context: ', context);
|
|
159
|
-
nunjucks_1.default.configure({
|
|
160
|
-
autoescape: true,
|
|
161
|
-
trimBlocks: true,
|
|
162
|
-
lstripBlocks: true,
|
|
163
|
-
});
|
|
164
|
-
return nunjucks_1.default.renderString(template, context);
|
|
165
|
-
}
|
|
166
|
-
return template;
|
|
167
|
-
}
|
|
168
|
-
return {
|
|
169
|
-
run,
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
return {
|
|
173
|
-
createWorkflow,
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
function createTranscript(logger, initialMessages) {
|
|
177
|
-
let finished = false;
|
|
178
|
-
const messages = [...initialMessages];
|
|
179
|
-
const directivesFormatter = (msg) => `${msg.sender}: ${msg.text}`;
|
|
180
|
-
const currentResponseFormatter = (partial) => `Current response: ${partial}`;
|
|
181
|
-
const responseTokens = [];
|
|
182
|
-
const names = {
|
|
183
|
-
agent: 'Agent',
|
|
184
|
-
user: 'User',
|
|
185
|
-
system: 'System',
|
|
186
|
-
};
|
|
187
|
-
return {
|
|
188
|
-
responseChunks: responseTokens,
|
|
189
|
-
get currentResponse() {
|
|
190
|
-
return responseTokens
|
|
191
|
-
.filter((token) => token.role === 'agent')
|
|
192
|
-
.map((token) => token?.delta)
|
|
193
|
-
.join('');
|
|
194
|
-
},
|
|
195
|
-
get mainResponseFinished() {
|
|
196
|
-
return finished;
|
|
197
|
-
},
|
|
198
|
-
get messages() {
|
|
199
|
-
return initialMessages;
|
|
200
|
-
},
|
|
201
|
-
markMainResponseFinished() {
|
|
202
|
-
logger.debug('Conversation, markMainResponseFinished');
|
|
203
|
-
finished = true;
|
|
204
|
-
},
|
|
205
|
-
toString(ignoreDirectives = false) {
|
|
206
|
-
const serializedMessages = messages
|
|
207
|
-
.map((msg) => {
|
|
208
|
-
if (msg.sender === 'system') {
|
|
209
|
-
return ignoreDirectives ? null : directivesFormatter(msg);
|
|
210
|
-
}
|
|
211
|
-
return `${names[msg.sender]}: ${msg.text}`;
|
|
212
|
-
})
|
|
213
|
-
.filter((line) => line !== null)
|
|
214
|
-
.join('\n');
|
|
215
|
-
if (responseTokens.length === 0) {
|
|
216
|
-
return serializedMessages;
|
|
217
|
-
}
|
|
218
|
-
return serializedMessages + '\n' + currentResponseFormatter(this.currentResponse);
|
|
219
|
-
},
|
|
220
|
-
getConversation() {
|
|
221
|
-
return messages;
|
|
222
|
-
},
|
|
223
|
-
};
|
|
224
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../../src/lib/stream/filter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAEjD;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,kBAc3B,CAAA"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.defaultFilter = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* filter out 'Agent:' at the beginning of the llm response
|
|
6
|
-
*/
|
|
7
|
-
exports.defaultFilter = {
|
|
8
|
-
shouldStartFiltering(state, newToken) {
|
|
9
|
-
return state.currentResponse.trim().length === 0 && newToken.toLowerCase() === 'agent';
|
|
10
|
-
},
|
|
11
|
-
onNewToken(_state, filteredTokens) {
|
|
12
|
-
if (filteredTokens.length >= 2 && filteredTokens[1] === ':') {
|
|
13
|
-
return { action: 'RELEASE_TOKENS', tokens: filteredTokens.slice(2) };
|
|
14
|
-
}
|
|
15
|
-
return { action: 'RELEASE_TOKENS', tokens: filteredTokens };
|
|
16
|
-
},
|
|
17
|
-
onStreamEnd(_state, filteredTokens) {
|
|
18
|
-
return { tokensToRelease: filteredTokens };
|
|
19
|
-
},
|
|
20
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../../src/lib/stream/interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AACtC,OAAO,EAAwB,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEzC,MAAM,WAAW,cAAc;IAC3B,iCAAiC;IACjC,cAAc,EAAE,CAAC,GAAG,SAAS,EAAE,EAC3B,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,KAC1B;QACD;;;;;WAKG;QACH,GAAG,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC,CAAA;KACjF,CAAA;CACJ;AAED,MAAM,WAAW,qBAAqB;IAClC,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,+DAA+D;IAC/D,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,iGAAiG;IACjG,UAAU,CAAC,EAAE,UAAU,CAAA;CAC1B;AAED,MAAM,WAAW,cAAc,CAAC,GAAG;IAC/B,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAA;IACZ,oBAAoB;IACpB,MAAM,EAAE,MAAM,GAAG,UAAU,CAAA;IAC3B,uCAAuC;IACvC,KAAK,EAAE,gBAAgB,CAAA;IACvB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3D,wCAAwC;IACxC,MAAM,CAAC,EAAE,kBAAkB,CAAA;CAC9B;AAED,MAAM,WAAW,UAAU;IACvB,cAAc,EAAE,aAAa,EAAE,CAAA;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAA;IACtC,wBAAwB,IAAI,IAAI,CAAA;IAChC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IAC5C,eAAe,IAAI,OAAO,EAAE,CAAA;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC7B;;;;OAIG;IACH,cAAc,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAA;IAC3F,0DAA0D;IAC1D,UAAU,EAAE,MAAM,OAAO,CAAA;CAC5B;AAED,MAAM,WAAW,kBAAkB;IAC/B,oBAAoB,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;IACtE,UAAU,EAAE,CACR,KAAK,EAAE,UAAU,EACjB,cAAc,EAAE,MAAM,EAAE,KACvB;QAAE,MAAM,EAAE,oBAAoB,CAAA;KAAE,GAAG;QAAE,MAAM,EAAE,gBAAgB,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;IACtF,WAAW,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK;QAAE,eAAe,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;CAC9F;AAED,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAA;IACxB,KAAK,EAAE,MAAM,CAAA;CAChB"}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|