@recombine-ai/engine 0.7.1 → 0.8.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/.github/workflows/linting.yml +32 -0
- package/.husky/post-merge +5 -0
- package/.husky/pre-commit +2 -0
- package/.husky/pre-push +5 -0
- package/build/lib/ai.d.ts +35 -48
- package/build/lib/ai.d.ts.map +1 -1
- package/build/lib/ai.js +82 -80
- package/build/lib/bosun/action.d.ts.map +1 -1
- package/build/lib/bosun/context.d.ts.map +1 -1
- package/build/lib/bosun/registry.d.ts +25 -0
- package/build/lib/bosun/registry.d.ts.map +1 -0
- package/build/lib/bosun/registry.js +35 -0
- package/build/lib/bosun/stepTracer.d.ts +3 -2
- package/build/lib/bosun/stepTracer.d.ts.map +1 -1
- package/build/lib/interfaces.d.ts.map +1 -1
- package/build/lib/platform.d.ts +16 -0
- package/build/lib/platform.d.ts.map +1 -0
- package/build/lib/platform.js +2 -0
- package/build/lib/schedule.d.ts.map +1 -1
- package/changelog.md +19 -1
- package/eslint.config.mjs +2 -0
- package/package.json +16 -2
- package/readme.md +47 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: lint & typecheck
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
checks:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
timeout-minutes: 10
|
|
12
|
+
steps:
|
|
13
|
+
- name: Checkout
|
|
14
|
+
uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Setup Node.js
|
|
17
|
+
uses: actions/setup-node@v4
|
|
18
|
+
with:
|
|
19
|
+
node-version: 24
|
|
20
|
+
cache: 'yarn'
|
|
21
|
+
|
|
22
|
+
- name: Install dependencies
|
|
23
|
+
run: yarn install --frozen-lockfile
|
|
24
|
+
|
|
25
|
+
- name: Run lint
|
|
26
|
+
run: yarn -s lint --quiet
|
|
27
|
+
|
|
28
|
+
- name: Run formatter check
|
|
29
|
+
run: yarn -s format:check
|
|
30
|
+
|
|
31
|
+
- name: Run typecheck
|
|
32
|
+
run: yarn -s typecheck
|
package/.husky/pre-push
ADDED
package/build/lib/ai.d.ts
CHANGED
|
@@ -7,20 +7,25 @@ import { Tracer } from './bosun';
|
|
|
7
7
|
/**
|
|
8
8
|
* Represents a basic model name for LLMs.
|
|
9
9
|
*/
|
|
10
|
-
export type BasicModel = 'o3-mini-2025-01-31' | 'o1-preview-2024-09-12' | 'gpt-4o-2024-11-20' | 'o1-2024-12-17' | (string & {});
|
|
11
|
-
export interface
|
|
12
|
-
/** Step name
|
|
10
|
+
export type BasicModel = 'o3-mini-2025-01-31' | 'o1-preview-2024-09-12' | 'gpt-4o-2024-08-06' | 'gpt-4o-2024-11-20' | 'gpt-4.1-2025-04-14' | 'o1-2024-12-17' | (string & {});
|
|
11
|
+
export interface BasicStep<CTX> {
|
|
12
|
+
/** Step name */
|
|
13
13
|
name: string;
|
|
14
14
|
/** Determines if the step should be run or not */
|
|
15
15
|
runIf?: (messages: Conversation, ctx: CTX) => boolean | Promise<boolean>;
|
|
16
|
-
/**
|
|
17
|
-
|
|
16
|
+
/**
|
|
17
|
+
* When provided, throws an error if the step is invoked more times than `maxAttempts`.
|
|
18
|
+
* Number of attempts taken is reset when the flow passed the step that was rewinding.
|
|
19
|
+
*/
|
|
20
|
+
maxAttempts?: number;
|
|
18
21
|
/** Error handler called if an error occurred during in `execute` function */
|
|
19
22
|
onError?: (error: string, ctx: CTX) => Promise<unknown>;
|
|
20
23
|
}
|
|
21
|
-
export interface
|
|
22
|
-
/**
|
|
23
|
-
|
|
24
|
+
export interface ProgrammaticStep<CTX> extends BasicStep<CTX> {
|
|
25
|
+
/** Content of the step */
|
|
26
|
+
execute: (messages: Conversation, ctx: CTX, workflow: WorkflowControls) => Promise<unknown>;
|
|
27
|
+
}
|
|
28
|
+
export interface LLMStep<CTX> extends BasicStep<CTX> {
|
|
24
29
|
/** Determines if the step should be run or not */
|
|
25
30
|
runIf?: (messages: Conversation, ctx: CTX) => boolean | Promise<boolean>;
|
|
26
31
|
/** LLM to use. Defaults to gpt-4o */
|
|
@@ -34,14 +39,17 @@ export interface LLMStep<CTX> {
|
|
|
34
39
|
* Do not put messages that were added via {@link Conversation.addMessage} into the prompt.
|
|
35
40
|
*/
|
|
36
41
|
ignoreAddedMessages?: boolean;
|
|
42
|
+
}
|
|
43
|
+
export interface WorkflowControls {
|
|
37
44
|
/**
|
|
38
|
-
*
|
|
39
|
-
* Number of attempts taken is reset when `shouldExecute` returns `false`. Useful to limit
|
|
40
|
-
* rewinds by reviewers. NOTE that it doesn't work on steps without `shouldExecute` method.
|
|
45
|
+
* Terminates the workflow, preventing further steps from being executed.
|
|
41
46
|
*/
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
|
|
47
|
+
terminate: () => void;
|
|
48
|
+
/**
|
|
49
|
+
* Rewinds the workflow execution to a specific step.
|
|
50
|
+
* @param step - The name of the step to rewind to
|
|
51
|
+
*/
|
|
52
|
+
rewindTo: (step: string) => void;
|
|
45
53
|
}
|
|
46
54
|
export interface JsonLLMStep<CTX, Schema extends ZodTypeAny> extends LLMStep<CTX> {
|
|
47
55
|
/**
|
|
@@ -65,13 +73,7 @@ export interface JsonLLMStep<CTX, Schema extends ZodTypeAny> extends LLMStep<CTX
|
|
|
65
73
|
* }
|
|
66
74
|
* ```
|
|
67
75
|
*/
|
|
68
|
-
execute: (reply: Zod.infer<Schema>, conversation: Conversation, ctx: CTX) => Promise<unknown>;
|
|
69
|
-
/**
|
|
70
|
-
* Check a condition, whether the `execute` function should run or not
|
|
71
|
-
* @deprecated use `runIf` to check if the step should be run, use if in `execute` to check
|
|
72
|
-
* if it should be executed
|
|
73
|
-
**/
|
|
74
|
-
shouldExecute?: (reply: Schema, ctx: CTX) => boolean | Promise<boolean>;
|
|
76
|
+
execute: (reply: Zod.infer<Schema>, conversation: Conversation, ctx: CTX, workflowControls: WorkflowControls) => Promise<unknown>;
|
|
75
77
|
}
|
|
76
78
|
export interface StringLLMStep<CTX> extends LLMStep<CTX> {
|
|
77
79
|
/**
|
|
@@ -89,39 +91,22 @@ export interface StringLLMStep<CTX> extends LLMStep<CTX> {
|
|
|
89
91
|
* }
|
|
90
92
|
* ```
|
|
91
93
|
*/
|
|
92
|
-
execute: (reply: string, conversation: Conversation, ctx: CTX) => Promise<unknown>;
|
|
93
|
-
/**
|
|
94
|
-
* Check a condition, whether the `execute` function should run or not
|
|
95
|
-
* @deprecated use `runIf` to check if the step should be run, use if in `execute` to check
|
|
96
|
-
* if it should be executed
|
|
97
|
-
**/
|
|
98
|
-
shouldExecute?: (reply: string, ctx: CTX) => boolean | Promise<boolean>;
|
|
94
|
+
execute: (reply: string, conversation: Conversation, ctx: CTX, workflowControls?: WorkflowControls) => Promise<unknown>;
|
|
99
95
|
}
|
|
96
|
+
type BeforeEachStep<CTX> = (conversation: Conversation, ctx: CTX, workflowControls?: WorkflowControls) => Promise<void>;
|
|
100
97
|
/**
|
|
101
98
|
* An AI workflow composed of steps.
|
|
102
99
|
*/
|
|
103
100
|
export interface Workflow<CTX> {
|
|
104
|
-
/**
|
|
105
|
-
* Terminates the workflow, preventing further steps from being executed.
|
|
106
|
-
*/
|
|
107
|
-
terminate: () => void;
|
|
108
101
|
/**
|
|
109
102
|
* Runs the workflow with a given conversation context.
|
|
110
103
|
* Executes steps sequentially until completion or termination.
|
|
111
|
-
* @param
|
|
104
|
+
* @param conversation - The conversation context for the workflow
|
|
105
|
+
* @param context – Context that will be passed to all steps and to all prompts in those steps
|
|
106
|
+
* @param beforeEach – A callback, that runs before each step
|
|
112
107
|
* @returns The proposed reply if workflow completes, or null if terminated
|
|
113
108
|
*/
|
|
114
|
-
run: (
|
|
115
|
-
/**
|
|
116
|
-
* Rewinds the workflow execution to a specific step.
|
|
117
|
-
* @param step - The step to rewind to
|
|
118
|
-
*/
|
|
119
|
-
rewindTo: (step: LLMStep<CTX> | ProgrammaticStep<CTX>) => void;
|
|
120
|
-
/**
|
|
121
|
-
* Registers a callback to be executed before each step.
|
|
122
|
-
* @param callback - Async function to execute before each step
|
|
123
|
-
*/
|
|
124
|
-
beforeEach: (callback: () => Promise<unknown>) => void;
|
|
109
|
+
run: (conversation: Conversation, context?: CTX, beforeEach?: BeforeEachStep<CTX>) => Promise<string | null>;
|
|
125
110
|
/**
|
|
126
111
|
* Add a step to workflow
|
|
127
112
|
*/
|
|
@@ -129,8 +114,11 @@ export interface Workflow<CTX> {
|
|
|
129
114
|
addStep(step: StringLLMStep<CTX>): void;
|
|
130
115
|
addStep(step: ProgrammaticStep<CTX>): void;
|
|
131
116
|
}
|
|
117
|
+
type WorkflowStep<CTX> = StringLLMStep<CTX> | JsonLLMStep<CTX, any> | ProgrammaticStep<CTX>;
|
|
132
118
|
export interface WorkflowConfig<CTX> {
|
|
133
119
|
onError: (error: string, ctx: CTX) => Promise<unknown>;
|
|
120
|
+
steps?: WorkflowStep<CTX>[];
|
|
121
|
+
beforeEachCallback?: () => Promise<unknown>;
|
|
134
122
|
}
|
|
135
123
|
interface StepBuilder<CTX> {
|
|
136
124
|
<Schema extends ZodTypeAny>(step: JsonLLMStep<CTX, Schema>): JsonLLMStep<CTX, Schema>;
|
|
@@ -194,7 +182,7 @@ export interface AIEngine {
|
|
|
194
182
|
* @param config - common parameters for a workflow
|
|
195
183
|
* @returns A Promise that resolves to the created Workflow.
|
|
196
184
|
*/
|
|
197
|
-
createWorkflow: <CTX>(config: WorkflowConfig<CTX>) => Workflow<CTX>;
|
|
185
|
+
createWorkflow: <CTX extends object>(config: WorkflowConfig<CTX>) => Workflow<CTX>;
|
|
198
186
|
/**
|
|
199
187
|
* Creates a new conversation instance.
|
|
200
188
|
* @param messages - Optional initial messages for the conversation.
|
|
@@ -250,7 +238,7 @@ export interface Conversation {
|
|
|
250
238
|
*/
|
|
251
239
|
setAgentName(name: string): void;
|
|
252
240
|
/**
|
|
253
|
-
* Sets the default formatter
|
|
241
|
+
* Sets the default formatter to stringify messages when toString is called.
|
|
254
242
|
* @param formatter - A function that takes a message and returns a formatted string.
|
|
255
243
|
*/
|
|
256
244
|
setDefaultFormatter: (formatter: (message: Message) => string) => void;
|
|
@@ -341,7 +329,6 @@ export interface EngineConfig {
|
|
|
341
329
|
* ```ts
|
|
342
330
|
* const engine = createAIEngine({
|
|
343
331
|
* logger: customLogger,
|
|
344
|
-
* basePath: '/path/to/prompts'
|
|
345
332
|
* });
|
|
346
333
|
*
|
|
347
334
|
* const workflow = await engine.createWorkflow(
|
|
@@ -356,7 +343,7 @@ export interface EngineConfig {
|
|
|
356
343
|
* ```
|
|
357
344
|
*/
|
|
358
345
|
export declare function createAIEngine(cfg?: EngineConfig): AIEngine;
|
|
359
|
-
declare function renderPrompt(prompt: string, context?:
|
|
346
|
+
declare function renderPrompt(prompt: string, context?: object): string;
|
|
360
347
|
export declare function createConversation(initialMessages?: Message[]): Conversation;
|
|
361
348
|
export declare function getStepBuilder<CTX = unknown>(): StepBuilder<CTX>;
|
|
362
349
|
export {};
|
package/build/lib/ai.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/lib/ai.ts"],"names":[],"mappings":"AAIA,OAAO,EAAa,UAAU,EAAK,MAAM,KAAK,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAAc,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAEvD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAa,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAIhC;;GAEG;AACH,MAAM,MAAM,UAAU,GAChB,oBAAoB,GACpB,uBAAuB,GACvB,mBAAmB,GACnB,eAAe,GACf,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;AAEnB,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/lib/ai.ts"],"names":[],"mappings":"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"}
|
package/build/lib/ai.js
CHANGED
|
@@ -7,7 +7,7 @@ exports.createAIEngine = createAIEngine;
|
|
|
7
7
|
exports.createConversation = createConversation;
|
|
8
8
|
exports.getStepBuilder = getStepBuilder;
|
|
9
9
|
// cspell:words lstripBlocks
|
|
10
|
-
const openai_1 =
|
|
10
|
+
const openai_1 = require("openai");
|
|
11
11
|
const nunjucks_1 = __importDefault(require("nunjucks"));
|
|
12
12
|
const zod_1 = require("zod");
|
|
13
13
|
const action_1 = require("./bosun/action");
|
|
@@ -26,7 +26,6 @@ const zod_to_json_schema_1 = require("zod-to-json-schema");
|
|
|
26
26
|
* ```ts
|
|
27
27
|
* const engine = createAIEngine({
|
|
28
28
|
* logger: customLogger,
|
|
29
|
-
* basePath: '/path/to/prompts'
|
|
30
29
|
* });
|
|
31
30
|
*
|
|
32
31
|
* const workflow = await engine.createWorkflow(
|
|
@@ -53,22 +52,15 @@ function createAIEngine(cfg = {}) {
|
|
|
53
52
|
throw new Error('OpenAI API key is not set');
|
|
54
53
|
},
|
|
55
54
|
};
|
|
56
|
-
function createWorkflow({ onError }) {
|
|
57
|
-
|
|
58
|
-
let currentStep = 0;
|
|
59
|
-
let beforeEachCallback = async () => Promise.resolve(null);
|
|
60
|
-
const attempts = new Map();
|
|
61
|
-
const steps = [];
|
|
55
|
+
function createWorkflow({ onError, steps = [], }) {
|
|
56
|
+
steps.forEach(addStepToTracer);
|
|
62
57
|
return {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
await beforeEachCallback();
|
|
70
|
-
const step = steps[currentStep];
|
|
71
|
-
if (!shouldRun) {
|
|
58
|
+
run: async (messages, ctx, beforeEach) => {
|
|
59
|
+
const state = new WorkflowState(logger, steps);
|
|
60
|
+
do {
|
|
61
|
+
await beforeEach?.(messages, ctx, state);
|
|
62
|
+
const step = state.getStep();
|
|
63
|
+
if (state.isTerminated()) {
|
|
72
64
|
logger.debug('AI Engine: run terminated');
|
|
73
65
|
break;
|
|
74
66
|
}
|
|
@@ -77,43 +69,32 @@ function createAIEngine(cfg = {}) {
|
|
|
77
69
|
await action('started');
|
|
78
70
|
logger.debug(`AI Engine: Step: ${step.name}`);
|
|
79
71
|
if ('prompt' in step) {
|
|
80
|
-
await runStep(step, messages, ctx,
|
|
72
|
+
await runStep(step, messages, ctx, state);
|
|
81
73
|
}
|
|
82
74
|
else {
|
|
83
|
-
await runProgrammaticStep(step, messages, ctx);
|
|
75
|
+
await runProgrammaticStep(step, messages, ctx, state);
|
|
84
76
|
}
|
|
85
77
|
await action('completed');
|
|
86
78
|
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return shouldRun ? messages.getProposedReply() : null;
|
|
90
|
-
},
|
|
91
|
-
rewindTo: (step) => {
|
|
92
|
-
const index = steps.indexOf(step);
|
|
93
|
-
if (index === -1) {
|
|
94
|
-
throw new Error(`Step ${step.name} not found`);
|
|
95
|
-
}
|
|
96
|
-
if (index > currentStep) {
|
|
97
|
-
throw new Error(`Cannot rewind to a step ahead of the current step`);
|
|
98
|
-
}
|
|
99
|
-
currentStep = index - 1; // -1 because it will be incremented in the loop definition
|
|
100
|
-
},
|
|
101
|
-
beforeEach(callback) {
|
|
102
|
-
beforeEachCallback = callback;
|
|
79
|
+
} while (state.next());
|
|
80
|
+
return state.isTerminated() ? null : messages.getProposedReply();
|
|
103
81
|
},
|
|
104
82
|
addStep(step) {
|
|
105
|
-
|
|
106
|
-
tracer.addStep({
|
|
107
|
-
name: step.name,
|
|
108
|
-
prompt: (0, tracer_1.stdPrompt)(step.prompt),
|
|
109
|
-
type: 'text',
|
|
110
|
-
schema: 'schema' in step ? step.schema : undefined,
|
|
111
|
-
});
|
|
112
|
-
}
|
|
83
|
+
addStepToTracer(step);
|
|
113
84
|
steps.push(step);
|
|
114
85
|
},
|
|
115
86
|
};
|
|
116
|
-
|
|
87
|
+
function addStepToTracer(step) {
|
|
88
|
+
if ('prompt' in step) {
|
|
89
|
+
tracer.addStep({
|
|
90
|
+
name: step.name,
|
|
91
|
+
prompt: (0, tracer_1.stdPrompt)(step.prompt),
|
|
92
|
+
type: 'text',
|
|
93
|
+
schema: 'schema' in step ? step.schema : undefined,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async function runStep(step, conversation, ctx, state) {
|
|
117
98
|
if (!apiKey) {
|
|
118
99
|
apiKey = await tokenStorage.getToken();
|
|
119
100
|
}
|
|
@@ -141,6 +122,7 @@ function createAIEngine(cfg = {}) {
|
|
|
141
122
|
const stringifiedMessages = conversation.toString({
|
|
142
123
|
ignoreAddedMessages: step.ignoreAddedMessages,
|
|
143
124
|
});
|
|
125
|
+
logger.debug('AI Engine stringified: ' + stringifiedMessages);
|
|
144
126
|
stepTrace.stringifiedConversation = stringifiedMessages;
|
|
145
127
|
stepTracer?.addStepTrace(stepTrace);
|
|
146
128
|
if ('schema' in step) {
|
|
@@ -153,22 +135,8 @@ function createAIEngine(cfg = {}) {
|
|
|
153
135
|
if (!response) {
|
|
154
136
|
throw new Error('No response from OpenAI');
|
|
155
137
|
}
|
|
156
|
-
logger.debug(`AI Engine: response
|
|
157
|
-
|
|
158
|
-
if (await step.shouldExecute(response, ctx)) {
|
|
159
|
-
logger.debug(`AI Engine: executing`);
|
|
160
|
-
checkAttempts(step);
|
|
161
|
-
await step.execute(response, conversation, ctx);
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
resetAttempts(step);
|
|
165
|
-
logger.debug(`AI Engine: skipping`);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
logger.debug(`AI Engine: replying`);
|
|
170
|
-
await step.execute(response, conversation, ctx);
|
|
171
|
-
}
|
|
138
|
+
logger.debug(`AI Engine: executing ${step.name}, LLM response`, response);
|
|
139
|
+
await step.execute(response, conversation, ctx, state);
|
|
172
140
|
}
|
|
173
141
|
catch (error) {
|
|
174
142
|
await (step.onError
|
|
@@ -176,37 +144,23 @@ function createAIEngine(cfg = {}) {
|
|
|
176
144
|
: onError(error.message, ctx));
|
|
177
145
|
// FIXME: this doesn't terminate the workflow
|
|
178
146
|
stepTracer?.addStepTrace(stepTrace);
|
|
179
|
-
|
|
147
|
+
state.terminate();
|
|
180
148
|
}
|
|
181
149
|
}
|
|
182
|
-
async function runProgrammaticStep(step, messages, ctx) {
|
|
150
|
+
async function runProgrammaticStep(step, messages, ctx, state) {
|
|
183
151
|
try {
|
|
184
152
|
if (!step.runIf || (await step.runIf(messages, ctx))) {
|
|
185
|
-
await step.execute(messages, ctx);
|
|
153
|
+
await step.execute(messages, ctx, state);
|
|
186
154
|
}
|
|
187
155
|
}
|
|
188
156
|
catch (error) {
|
|
189
|
-
|
|
157
|
+
logger.error(`AI Engine: error in dumb step ${step.name}: ${error.message}`);
|
|
190
158
|
await (step.onError
|
|
191
159
|
? step.onError(error.message, ctx)
|
|
192
160
|
: onError(error.message, ctx));
|
|
193
|
-
|
|
161
|
+
state.terminate();
|
|
194
162
|
}
|
|
195
163
|
}
|
|
196
|
-
function checkAttempts(step) {
|
|
197
|
-
if (step.maxAttempts) {
|
|
198
|
-
if (!attempts.has(step)) {
|
|
199
|
-
attempts.set(step, 0);
|
|
200
|
-
}
|
|
201
|
-
attempts.set(step, attempts.get(step) + 1);
|
|
202
|
-
if (attempts.get(step) > step.maxAttempts) {
|
|
203
|
-
throw new Error(`Max attempts reached for step ${step.name}`);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
function resetAttempts(step) {
|
|
208
|
-
attempts.set(step, 0);
|
|
209
|
-
}
|
|
210
164
|
}
|
|
211
165
|
async function runLLM(apiKey, systemPrompt, messages, schema, model = 'gpt-4o-2024-08-06') {
|
|
212
166
|
logger.debug('AI Engine: model:', model);
|
|
@@ -220,7 +174,7 @@ function createAIEngine(cfg = {}) {
|
|
|
220
174
|
}
|
|
221
175
|
return JSON.stringify({ message: 'canned response', reasons: [] });
|
|
222
176
|
}
|
|
223
|
-
const client = new openai_1.
|
|
177
|
+
const client = new openai_1.OpenAI({ apiKey });
|
|
224
178
|
const response = await client.chat.completions.create({
|
|
225
179
|
messages: [
|
|
226
180
|
{ role: 'system', content: systemPrompt },
|
|
@@ -242,6 +196,54 @@ function createAIEngine(cfg = {}) {
|
|
|
242
196
|
},
|
|
243
197
|
};
|
|
244
198
|
}
|
|
199
|
+
class WorkflowState {
|
|
200
|
+
logger;
|
|
201
|
+
steps;
|
|
202
|
+
shouldRun = true;
|
|
203
|
+
currentStep = 0;
|
|
204
|
+
/** map, step index to number of attempts */
|
|
205
|
+
attempts = new Map();
|
|
206
|
+
rewinder = 0;
|
|
207
|
+
lastRewindTo = 0;
|
|
208
|
+
constructor(logger, steps) {
|
|
209
|
+
this.logger = logger;
|
|
210
|
+
this.steps = steps;
|
|
211
|
+
}
|
|
212
|
+
terminate() {
|
|
213
|
+
this.logger.debug('AI Engine: Terminating conversation...');
|
|
214
|
+
this.shouldRun = false;
|
|
215
|
+
}
|
|
216
|
+
isTerminated() {
|
|
217
|
+
return !this.shouldRun;
|
|
218
|
+
}
|
|
219
|
+
getStep() {
|
|
220
|
+
return this.steps[this.currentStep] || null;
|
|
221
|
+
}
|
|
222
|
+
next() {
|
|
223
|
+
this.currentStep++;
|
|
224
|
+
if (this.rewinder < this.currentStep) {
|
|
225
|
+
this.attempts.delete(this.lastRewindTo);
|
|
226
|
+
}
|
|
227
|
+
return this.currentStep < this.steps.length;
|
|
228
|
+
}
|
|
229
|
+
rewindTo(stepName) {
|
|
230
|
+
this.rewinder = this.currentStep;
|
|
231
|
+
const index = this.steps.findIndex((s) => s.name === stepName);
|
|
232
|
+
if (index < 0) {
|
|
233
|
+
const names = this.steps.map((s) => s.name).join(', ');
|
|
234
|
+
throw new Error(`Tried to rewind to ${stepName}, steps: [${names}]`);
|
|
235
|
+
}
|
|
236
|
+
this.currentStep = index - 1; // -1 because .next() will be called right after
|
|
237
|
+
this.lastRewindTo = this.currentStep;
|
|
238
|
+
const step = this.steps[index];
|
|
239
|
+
const max = step.maxAttempts || 10;
|
|
240
|
+
const attempt = this.attempts.get(this.currentStep) ?? 1;
|
|
241
|
+
if (attempt >= max) {
|
|
242
|
+
throw new Error(`Max attempts reached for step ${step.name}`);
|
|
243
|
+
}
|
|
244
|
+
this.attempts.set(this.currentStep, attempt + 1);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
245
247
|
function getOpenAiOptions(model, schema) {
|
|
246
248
|
const options = {
|
|
247
249
|
model,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../../src/lib/bosun/action.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAA;IACzC,OAAO,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAE1D,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../../src/lib/bosun/action.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAA;IACzC,OAAO,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAE1D,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,IAEhD,SAAS,MAAM,EACf,MAAM,MAAM,EACZ,QAAQ,MAAM,OAAO,CAAC,OAAO,CAAC,mBAiBrC;AAED,wBAAgB,UAAU,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,YAM1D,MAAM,CAAC,OAAO,CAAC,mBAQhD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/lib/bosun/context.ts"],"names":[],"mappings":"AAAA,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AAC9B,KAAK,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,GAC1B;KACK,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC5C,CAAC,MAAM,CAAC,CAAC,GACV,KAAK,CAAA;AAEX,KAAK,SAAS,CAAC,CAAC,EAAE,CAAC,SAAS,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,GACrE,KAAK,SAAS,MAAM,CAAC,GACjB,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GACpB,CAAC,CAAC,KAAK,CAAC,GACR,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,GAC7B,KAAK,GACT,KAAK,CAAA;AAEX,cAAM,OAAO,CAAC,CAAC,SAAS,GAAG;;gBAGX,OAAO,EAAE,CAAC;IAItB,GAAG,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,SAAS,GAAG,EAAE,GAAG,CAAC,GAAG,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI;IACxF,GAAG,CAAC,UAAU,EAAE,CAAC,GAAG,IAAI;IAgBxB,GAAG;IAIH,gCAAgC;IAChC,IAAI,CAAC,UAAU,EAAE,CAAC;IAIlB,SAAS,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/lib/bosun/context.ts"],"names":[],"mappings":"AAAA,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AAC9B,KAAK,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,GAC1B;KACK,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC5C,CAAC,MAAM,CAAC,CAAC,GACV,KAAK,CAAA;AAEX,KAAK,SAAS,CAAC,CAAC,EAAE,CAAC,SAAS,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,GACrE,KAAK,SAAS,MAAM,CAAC,GACjB,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GACpB,CAAC,CAAC,KAAK,CAAC,GACR,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,GAC7B,KAAK,GACT,KAAK,CAAA;AAEX,cAAM,OAAO,CAAC,CAAC,SAAS,GAAG;;gBAGX,OAAO,EAAE,CAAC;IAItB,GAAG,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,SAAS,GAAG,EAAE,GAAG,CAAC,GAAG,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI;IACxF,GAAG,CAAC,UAAU,EAAE,CAAC,GAAG,IAAI;IAgBxB,GAAG;IAIH,gCAAgC;IAChC,IAAI,CAAC,UAAU,EAAE,CAAC;IAIlB,SAAS,GAAI,UAAU,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,mBAG1C;CACJ;AAED,wBAAgB,aAAa,CAAC,CAAC,SAAS,GAAG,EAAE,OAAO,EAAE,CAAC,cAEtD;AAED,KAAK,MAAM,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,CAAA;AAEzC,KAAK,aAAa,CAAC,CAAC,SAAS,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;AAEtD,YAAY,EAAE,aAAa,IAAI,OAAO,EAAE,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ZodSchema } from 'zod';
|
|
2
|
+
import { PromptFile } from '../prompt-fs';
|
|
3
|
+
import { Logger } from '../interfaces';
|
|
4
|
+
export interface PromptString {
|
|
5
|
+
type: 'string';
|
|
6
|
+
content: () => Promise<string>;
|
|
7
|
+
}
|
|
8
|
+
export interface StepDef {
|
|
9
|
+
name: string;
|
|
10
|
+
workflow: string;
|
|
11
|
+
type: 'streaming-response' | 'streaming-detect' | 'text';
|
|
12
|
+
prompt?: PromptFile | PromptString;
|
|
13
|
+
schema?: ZodSchema;
|
|
14
|
+
}
|
|
15
|
+
export interface WorkflowDef {
|
|
16
|
+
name: string;
|
|
17
|
+
type: 'stream' | 'text';
|
|
18
|
+
}
|
|
19
|
+
export interface Registry {
|
|
20
|
+
addStep(def: StepDef): void;
|
|
21
|
+
addWorkflow(def: WorkflowDef): void;
|
|
22
|
+
}
|
|
23
|
+
export declare function createConsoleRegistry(logger: Logger): Registry;
|
|
24
|
+
export declare function stdPrompt(prompt: PromptFile | string): PromptString | PromptFile;
|
|
25
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/lib/bosun/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAEtC,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,QAAQ,CAAA;IACd,OAAO,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;CACjC;AAED,MAAM,WAAW,OAAO;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,oBAAoB,GAAG,kBAAkB,GAAG,MAAM,CAAA;IACxD,MAAM,CAAC,EAAE,UAAU,GAAG,YAAY,CAAA;IAClC,MAAM,CAAC,EAAE,SAAS,CAAA;CACrB;AACD,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,QAAQ;IACrB,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAAA;IAC3B,WAAW,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAAA;CACtC;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAoB9D;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,6BAQpD"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createConsoleRegistry = createConsoleRegistry;
|
|
4
|
+
exports.stdPrompt = stdPrompt;
|
|
5
|
+
function createConsoleRegistry(logger) {
|
|
6
|
+
return {
|
|
7
|
+
addStep(def) {
|
|
8
|
+
let msg = `Registry, step added: ${def.name} (${def.type}) to ${def.workflow}`;
|
|
9
|
+
if (def.prompt) {
|
|
10
|
+
if (def.prompt.type === 'string') {
|
|
11
|
+
msg += ' with inline prompt';
|
|
12
|
+
}
|
|
13
|
+
else if (def.prompt.type === 'file') {
|
|
14
|
+
msg += ` with prompt ${def.prompt.path}`;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
if (def.schema) {
|
|
18
|
+
msg += ' with schema';
|
|
19
|
+
}
|
|
20
|
+
logger.debug(msg + '.');
|
|
21
|
+
},
|
|
22
|
+
addWorkflow(def) {
|
|
23
|
+
logger.debug('Registry, workflow added:', def.name, `(${def.type})`);
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function stdPrompt(prompt) {
|
|
28
|
+
if (typeof prompt === 'string') {
|
|
29
|
+
return {
|
|
30
|
+
type: 'string',
|
|
31
|
+
content: async () => prompt,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return prompt;
|
|
35
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { ZodSchema } from 'zod';
|
|
2
|
+
import { PromptFile } from '../prompt-fs';
|
|
2
3
|
export type StepTrace = {
|
|
3
4
|
name: string;
|
|
4
5
|
renderedPrompt?: string;
|
|
5
|
-
receivedContext?:
|
|
6
|
-
receivedPrompt?: string |
|
|
6
|
+
receivedContext?: unknown;
|
|
7
|
+
receivedPrompt?: string | PromptFile;
|
|
7
8
|
stringifiedConversation?: string;
|
|
8
9
|
schema?: ZodSchema;
|
|
9
10
|
model?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stepTracer.d.ts","sourceRoot":"","sources":["../../../src/lib/bosun/stepTracer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"stepTracer.d.ts","sourceRoot":"","sources":["../../../src/lib/bosun/stepTracer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEzC,MAAM,MAAM,SAAS,GAAG;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,cAAc,CAAC,EAAE,MAAM,GAAG,UAAU,CAAA;IACpC,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,WAAW,UAAU;IACvB,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAA;CAC3C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../src/lib/interfaces.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IACnB,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAA;IAC7B,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAA;IAC/B,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAA;CAClC;AAED;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../src/lib/interfaces.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IACnB,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAA;IAC7B,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAA;IAC/B,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAA;CAClC;AAED;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAE1E,MAAM,WAAW,SAAS;IACtB;;;;;OAKG;IACH,cAAc,EAAE,CACZ,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,KAC1C,cAAc,CAAA;IAEnB;;OAEG;IACH,sBAAsB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAC9D"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { AIEngine } from './ai';
|
|
2
|
+
import { Logger } from './interfaces';
|
|
3
|
+
import { PromptFS } from './prompt-fs';
|
|
4
|
+
export interface Platform<TConf = {}> {
|
|
5
|
+
/** Streaming AI engine, used to create streaming workflows to be used in voice agents */
|
|
6
|
+
streamAi: any;
|
|
7
|
+
/** String-base AI engine, used in text agents or for analysis of the conversation */
|
|
8
|
+
ai: AIEngine;
|
|
9
|
+
/** File system, used to load prompt files */
|
|
10
|
+
fs: PromptFS;
|
|
11
|
+
/** Handles to mange calls, e.g. re-run stream response, hangup, etc. */
|
|
12
|
+
rcVoice: any;
|
|
13
|
+
/** Platform and agent-specific configuration variables, e.g. trunk setup, voice settings etc. */
|
|
14
|
+
logger: Logger;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=platform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../src/lib/platform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEtC,MAAM,WAAW,QAAQ,CAAC,KAAK,GAAG,EAAE;IAChC,yFAAyF;IAEzF,QAAQ,EAAE,GAAG,CAAA;IACb,qFAAqF;IACrF,EAAE,EAAE,QAAQ,CAAA;IACZ,6CAA6C;IAC7C,EAAE,EAAE,QAAQ,CAAA;IACZ,wEAAwE;IAExE,OAAO,EAAE,GAAG,CAAA;IACZ,iGAAiG;IAEjG,MAAM,EAAE,MAAM,CAAA;CACjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../../src/lib/schedule.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../../src/lib/schedule.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,IACV,OAAO,KAAK,KAAG,IAAI,CAGvD;AAED;;GAEG;AACH,qBAAa,aAAa;IACV,OAAO,CAAC,QAAQ;gBAAR,QAAQ,EAAE,QAAQ;IAEtC;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAEjC;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAuC/B,0DAA0D;IAC1D,IAAI;IAIJ;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,IAAI;CAIrB;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,iBAErD;AAiFD,KAAK,KAAK,GACJ,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC,GACtC,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,GACpC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,GACjC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,CAAA;AAE1D,KAAK,SAAS,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;AACtD,KAAK,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAC/D,KAAK,IAAI,GAAG,GAAG,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,EAAE,CAAA;AAC3D,KAAK,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAA;AAClG,KAAK,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAC1D,KAAK,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAE9F,KAAK,OAAO,GAAG,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,EAAE,CAAA;AAE9D,UAAU,SAAS;IACf,IAAI,EAAE,QAAQ,EAAE,CAAA;IAChB,IAAI,EAAE,IAAI,CAAA;IACV,EAAE,EAAE,IAAI,CAAA;CACX;AAED,MAAM,WAAW,QAAQ;IACrB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,SAAS,EAAE,CAAA;IAC1B,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;CACvB"}
|
package/changelog.md
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
### 0.
|
|
3
|
+
### 0.7.1 → 0.8.0 (unstable)
|
|
4
|
+
|
|
5
|
+
Breaking changes:
|
|
6
|
+
|
|
7
|
+
- `WorkflowControls` parameter added to step `execute` methods - all `ProgrammaticStep`,
|
|
8
|
+
`StringLLMStep`, and `JsonLLMStep` execute functions now receive workflow controls as the last
|
|
9
|
+
parameter,
|
|
10
|
+
- `Workflow.terminate()` and `Workflow.rewindTo()` methods removed - use
|
|
11
|
+
`WorkflowControls.terminate()` and `WorkflowControls.rewindTo()` from within step execution
|
|
12
|
+
instead, note that `WorkflowControls.rewindTo()` accept step name, rather then link to a step,
|
|
13
|
+
- `shouldExecute` property removed from `StringLLMStep` and `JsonLLMStep` interfaces - use
|
|
14
|
+
conditional logic within the `execute` function.
|
|
15
|
+
- `beforeEach` callback also moved into `Workflow.run` as third parameter
|
|
16
|
+
|
|
17
|
+
Other changes:
|
|
18
|
+
|
|
19
|
+
- Added support for additional OpenAI models: `gpt-4o-2024-08-06` and `gpt-4.1-2025-04-14`.
|
|
20
|
+
|
|
21
|
+
### 0.7.0 → 0.7.1 (unstable)
|
|
4
22
|
|
|
5
23
|
- fixed multiple runs on static workflows
|
|
6
24
|
|
package/eslint.config.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@recombine-ai/engine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Recombine AI engine for creating conversational AI agents",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -10,12 +10,15 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"dev": "tsc -w",
|
|
12
12
|
"build": "tsc",
|
|
13
|
+
"typecheck": "tsc --noEmit",
|
|
13
14
|
"prepublishOnly": "npm run build",
|
|
14
15
|
"test": "vitest",
|
|
15
16
|
"docs": "cd docusaurus && yarn build --out-dir ../docs && cd ..",
|
|
16
17
|
"lint": "eslint",
|
|
17
18
|
"lint:fix": "eslint --fix",
|
|
18
|
-
"format": "prettier --write ."
|
|
19
|
+
"format": "prettier --write .",
|
|
20
|
+
"format:check": "prettier --check .",
|
|
21
|
+
"prepare": "husky"
|
|
19
22
|
},
|
|
20
23
|
"devDependencies": {
|
|
21
24
|
"@eslint/js": "^9.26.0",
|
|
@@ -23,6 +26,8 @@
|
|
|
23
26
|
"@types/nunjucks": "^3.2.6",
|
|
24
27
|
"@typescript-eslint/eslint-plugin": "^8.32.0",
|
|
25
28
|
"eslint": "^9.26.0",
|
|
29
|
+
"husky": "^9.1.7",
|
|
30
|
+
"lint-staged": "^16.2.4",
|
|
26
31
|
"prettier": "^3.3.3",
|
|
27
32
|
"typescript": "^5.8.3",
|
|
28
33
|
"typescript-eslint": "^8.32.0",
|
|
@@ -33,5 +38,14 @@
|
|
|
33
38
|
"openai": "^4.68.4",
|
|
34
39
|
"zod": "3.23.8",
|
|
35
40
|
"zod-to-json-schema": "^3.24.6"
|
|
41
|
+
},
|
|
42
|
+
"husky": {
|
|
43
|
+
"hooks": {}
|
|
44
|
+
},
|
|
45
|
+
"lint-staged": {
|
|
46
|
+
"*.{ts,tsx,js,jsx,json,md}": [
|
|
47
|
+
"pnpm format",
|
|
48
|
+
"pnpm lint:fix"
|
|
49
|
+
]
|
|
36
50
|
}
|
|
37
51
|
}
|
package/readme.md
CHANGED
|
@@ -101,3 +101,50 @@ workflow.terminate() // usually used in kill-switch or error handlers: terminate
|
|
|
101
101
|
workflow.rewind(step) // restart workflow from a particular step
|
|
102
102
|
workflow.beforeEach(callback) // a callback to run before each step, e.g. to terminate workflow due to some external reasons
|
|
103
103
|
```
|
|
104
|
+
|
|
105
|
+
## Development
|
|
106
|
+
|
|
107
|
+
### Setting Up the Development Environment
|
|
108
|
+
|
|
109
|
+
To contribute to this project, you'll need to set up your local development environment:
|
|
110
|
+
|
|
111
|
+
1. **Install dependencies:**
|
|
112
|
+
|
|
113
|
+
```sh
|
|
114
|
+
yarn install
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
This project uses `yarn` as its package manager. If you don't have it installed, you can install it with:
|
|
118
|
+
|
|
119
|
+
```sh
|
|
120
|
+
npm install -g yarn
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
2. **Set up Git hooks with Husky:**
|
|
124
|
+
|
|
125
|
+
Git hooks are automatically installed when you run `yarn install` (via the `prepare` script). The project uses Husky to manage the following Git hooks:
|
|
126
|
+
|
|
127
|
+
- **`pre-commit`**: Runs `lint-staged` to format and lint only staged files using Prettier and ESLint
|
|
128
|
+
- **`pre-push`**: Runs TypeScript type checking to ensure no type errors before pushing
|
|
129
|
+
- **`post-merge`**: Automatically runs `yarn install` if `package.json` or `yarn.yaml` changed after a merge
|
|
130
|
+
|
|
131
|
+
### Available Scripts
|
|
132
|
+
|
|
133
|
+
- **`yarn dev`** - Start TypeScript compiler in watch mode
|
|
134
|
+
- **`yarn build`** - Build the project
|
|
135
|
+
- **`yarn typecheck`** - Run TypeScript type checking without emitting files
|
|
136
|
+
- **`yarn test`** - Run tests with Vitest
|
|
137
|
+
- **`yarn lint`** - Lint code with ESLint
|
|
138
|
+
- **`yarn lint:fix`** - Lint and automatically fix issues
|
|
139
|
+
- **`yarn format`** - Format code with Prettier
|
|
140
|
+
- **`yarn format:check`** - Check code formatting without making changes
|
|
141
|
+
|
|
142
|
+
### Code Quality
|
|
143
|
+
|
|
144
|
+
The project maintains code quality through:
|
|
145
|
+
|
|
146
|
+
- **TypeScript** for type safety
|
|
147
|
+
- **ESLint** for code linting
|
|
148
|
+
- **Prettier** for consistent code formatting
|
|
149
|
+
- **Vitest** for testing
|
|
150
|
+
- **Husky + lint-staged** for automated pre-commit checks
|