@recombine-ai/engine 0.8.0-draft → 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 +33 -50
- package/build/lib/ai.d.ts.map +1 -1
- package/build/lib/ai.js +82 -95
- 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 +1 -1
- 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
|
@@ -8,19 +8,24 @@ import { Tracer } from './bosun';
|
|
|
8
8
|
* Represents a basic model name for LLMs.
|
|
9
9
|
*/
|
|
10
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
|
|
12
|
-
/** Step name
|
|
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,18 +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
|
-
maxAttempts?: number;
|
|
43
|
-
/** Error handler called if an error occurred during LLM API call or in `execute` function */
|
|
44
|
-
onError?: (error: string, ctx: CTX) => Promise<unknown>;
|
|
45
|
-
}
|
|
46
|
-
export interface WorkflowControls<CTX> {
|
|
47
47
|
terminate: () => void;
|
|
48
|
-
|
|
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;
|
|
49
53
|
}
|
|
50
54
|
export interface JsonLLMStep<CTX, Schema extends ZodTypeAny> extends LLMStep<CTX> {
|
|
51
55
|
/**
|
|
@@ -69,13 +73,7 @@ export interface JsonLLMStep<CTX, Schema extends ZodTypeAny> extends LLMStep<CTX
|
|
|
69
73
|
* }
|
|
70
74
|
* ```
|
|
71
75
|
*/
|
|
72
|
-
execute: (reply: Zod.infer<Schema>, conversation: Conversation, ctx: CTX, workflowControls
|
|
73
|
-
/**
|
|
74
|
-
* Check a condition, whether the `execute` function should run or not
|
|
75
|
-
* @deprecated use `runIf` to check if the step should be run, use if in `execute` to check
|
|
76
|
-
* if it should be executed
|
|
77
|
-
**/
|
|
78
|
-
shouldExecute?: (reply: Schema, ctx: CTX) => boolean | Promise<boolean>;
|
|
76
|
+
execute: (reply: Zod.infer<Schema>, conversation: Conversation, ctx: CTX, workflowControls: WorkflowControls) => Promise<unknown>;
|
|
79
77
|
}
|
|
80
78
|
export interface StringLLMStep<CTX> extends LLMStep<CTX> {
|
|
81
79
|
/**
|
|
@@ -93,39 +91,22 @@ export interface StringLLMStep<CTX> extends LLMStep<CTX> {
|
|
|
93
91
|
* }
|
|
94
92
|
* ```
|
|
95
93
|
*/
|
|
96
|
-
execute: (reply: string, conversation: Conversation, ctx: CTX, workflowControls?: WorkflowControls
|
|
97
|
-
/**
|
|
98
|
-
* Check a condition, whether the `execute` function should run or not
|
|
99
|
-
* @deprecated use `runIf` to check if the step should be run, use if in `execute` to check
|
|
100
|
-
* if it should be executed
|
|
101
|
-
**/
|
|
102
|
-
shouldExecute?: (reply: string, ctx: CTX) => boolean | Promise<boolean>;
|
|
94
|
+
execute: (reply: string, conversation: Conversation, ctx: CTX, workflowControls?: WorkflowControls) => Promise<unknown>;
|
|
103
95
|
}
|
|
96
|
+
type BeforeEachStep<CTX> = (conversation: Conversation, ctx: CTX, workflowControls?: WorkflowControls) => Promise<void>;
|
|
104
97
|
/**
|
|
105
98
|
* An AI workflow composed of steps.
|
|
106
99
|
*/
|
|
107
100
|
export interface Workflow<CTX> {
|
|
108
|
-
/**
|
|
109
|
-
* Terminates the workflow, preventing further steps from being executed.
|
|
110
|
-
*/
|
|
111
|
-
terminate: () => void;
|
|
112
101
|
/**
|
|
113
102
|
* Runs the workflow with a given conversation context.
|
|
114
103
|
* Executes steps sequentially until completion or termination.
|
|
115
|
-
* @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
|
|
116
107
|
* @returns The proposed reply if workflow completes, or null if terminated
|
|
117
108
|
*/
|
|
118
|
-
run: (
|
|
119
|
-
/**
|
|
120
|
-
* Rewinds the workflow execution to a specific step.
|
|
121
|
-
* @param step - The step to rewind to
|
|
122
|
-
*/
|
|
123
|
-
rewindTo: (step: LLMStep<CTX> | ProgrammaticStep<CTX>) => void;
|
|
124
|
-
/**
|
|
125
|
-
* Registers a callback to be executed before each step.
|
|
126
|
-
* @param callback - Async function to execute before each step
|
|
127
|
-
*/
|
|
128
|
-
beforeEach: (callback: () => Promise<unknown>) => void;
|
|
109
|
+
run: (conversation: Conversation, context?: CTX, beforeEach?: BeforeEachStep<CTX>) => Promise<string | null>;
|
|
129
110
|
/**
|
|
130
111
|
* Add a step to workflow
|
|
131
112
|
*/
|
|
@@ -133,8 +114,11 @@ export interface Workflow<CTX> {
|
|
|
133
114
|
addStep(step: StringLLMStep<CTX>): void;
|
|
134
115
|
addStep(step: ProgrammaticStep<CTX>): void;
|
|
135
116
|
}
|
|
117
|
+
type WorkflowStep<CTX> = StringLLMStep<CTX> | JsonLLMStep<CTX, any> | ProgrammaticStep<CTX>;
|
|
136
118
|
export interface WorkflowConfig<CTX> {
|
|
137
119
|
onError: (error: string, ctx: CTX) => Promise<unknown>;
|
|
120
|
+
steps?: WorkflowStep<CTX>[];
|
|
121
|
+
beforeEachCallback?: () => Promise<unknown>;
|
|
138
122
|
}
|
|
139
123
|
interface StepBuilder<CTX> {
|
|
140
124
|
<Schema extends ZodTypeAny>(step: JsonLLMStep<CTX, Schema>): JsonLLMStep<CTX, Schema>;
|
|
@@ -198,7 +182,7 @@ export interface AIEngine {
|
|
|
198
182
|
* @param config - common parameters for a workflow
|
|
199
183
|
* @returns A Promise that resolves to the created Workflow.
|
|
200
184
|
*/
|
|
201
|
-
createWorkflow: <CTX>(config: WorkflowConfig<CTX>) => Workflow<CTX>;
|
|
185
|
+
createWorkflow: <CTX extends object>(config: WorkflowConfig<CTX>) => Workflow<CTX>;
|
|
202
186
|
/**
|
|
203
187
|
* Creates a new conversation instance.
|
|
204
188
|
* @param messages - Optional initial messages for the conversation.
|
|
@@ -254,7 +238,7 @@ export interface Conversation {
|
|
|
254
238
|
*/
|
|
255
239
|
setAgentName(name: string): void;
|
|
256
240
|
/**
|
|
257
|
-
* Sets the default formatter
|
|
241
|
+
* Sets the default formatter to stringify messages when toString is called.
|
|
258
242
|
* @param formatter - A function that takes a message and returns a formatted string.
|
|
259
243
|
*/
|
|
260
244
|
setDefaultFormatter: (formatter: (message: Message) => string) => void;
|
|
@@ -345,7 +329,6 @@ export interface EngineConfig {
|
|
|
345
329
|
* ```ts
|
|
346
330
|
* const engine = createAIEngine({
|
|
347
331
|
* logger: customLogger,
|
|
348
|
-
* basePath: '/path/to/prompts'
|
|
349
332
|
* });
|
|
350
333
|
*
|
|
351
334
|
* const workflow = await engine.createWorkflow(
|
|
@@ -360,7 +343,7 @@ export interface EngineConfig {
|
|
|
360
343
|
* ```
|
|
361
344
|
*/
|
|
362
345
|
export declare function createAIEngine(cfg?: EngineConfig): AIEngine;
|
|
363
|
-
declare function renderPrompt(prompt: string, context?:
|
|
346
|
+
declare function renderPrompt(prompt: string, context?: object): string;
|
|
364
347
|
export declare function createConversation(initialMessages?: Message[]): Conversation;
|
|
365
348
|
export declare function getStepBuilder<CTX = unknown>(): StepBuilder<CTX>;
|
|
366
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,mBAAmB,GACnB,oBAAoB,GACpB,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":"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,mBAAmB,GACnB,oBAAoB,GACpB,eAAe,GACf,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;AAEnB,MAAM,WAAW,SAAS,CAAC,GAAG;IAC1B,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAA;IAEZ,kDAAkD;IAClD,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAExE;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAC1D;AAED,MAAM,WAAW,gBAAgB,CAAC,GAAG,CAAE,SAAQ,SAAS,CAAC,GAAG,CAAC;IACzD,0BAA0B;IAC1B,OAAO,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,gBAAgB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAC9F;AAED,MAAM,WAAW,OAAO,CAAC,GAAG,CAAE,SAAQ,SAAS,CAAC,GAAG,CAAC;IAChD,kDAAkD;IAClD,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAExE,qCAAqC;IACrC,KAAK,CAAC,EAAE,UAAU,CAAA;IAElB;;;OAGG;IACH,MAAM,EAAE,MAAM,GAAG,UAAU,CAAA;IAE3B;;OAEG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC7B;;OAEG;IACH,SAAS,EAAE,MAAM,IAAI,CAAA;IAErB;;;OAGG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CACnC;AAED,MAAM,WAAW,WAAW,CAAC,GAAG,EAAE,MAAM,SAAS,UAAU,CAAE,SAAQ,OAAO,CAAC,GAAG,CAAC;IAC7E;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;;;;;;;;;;;;;OAcG;IACH,OAAO,EAAE,CACL,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EACxB,YAAY,EAAE,YAAY,EAC1B,GAAG,EAAE,GAAG,EACR,gBAAgB,EAAE,gBAAgB,KACjC,OAAO,CAAC,OAAO,CAAC,CAAA;CACxB;AAED,MAAM,WAAW,aAAa,CAAC,GAAG,CAAE,SAAQ,OAAO,CAAC,GAAG,CAAC;IACpD;;;;;;;;;;;;;;OAcG;IACH,OAAO,EAAE,CACL,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,YAAY,EAC1B,GAAG,EAAE,GAAG,EACR,gBAAgB,CAAC,EAAE,gBAAgB,KAClC,OAAO,CAAC,OAAO,CAAC,CAAA;CACxB;AAED,KAAK,cAAc,CAAC,GAAG,IAAI,CACvB,YAAY,EAAE,YAAY,EAC1B,GAAG,EAAE,GAAG,EACR,gBAAgB,CAAC,EAAE,gBAAgB,KAClC,OAAO,CAAC,IAAI,CAAC,CAAA;AAElB;;GAEG;AACH,MAAM,WAAW,QAAQ,CAAC,GAAG;IACzB;;;;;;;OAOG;IACH,GAAG,EAAE,CACD,YAAY,EAAE,YAAY,EAC1B,OAAO,CAAC,EAAE,GAAG,EACb,UAAU,CAAC,EAAE,cAAc,CAAC,GAAG,CAAC,KAC/B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IAE3B;;OAEG;IACH,OAAO,CAAC,MAAM,SAAS,UAAU,EAAE,IAAI,EAAE,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,CAAA;IACxE,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;IACvC,OAAO,CAAC,IAAI,EAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;CAC7C;AAED,KAAK,YAAY,CAAC,GAAG,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAA;AAE3F,MAAM,WAAW,cAAc,CAAC,GAAG;IAC/B,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACtD,KAAK,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,CAAA;IAC3B,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;CAC9C;AAED,UAAU,WAAW,CAAC,GAAG;IACrB,CAAC,MAAM,SAAS,UAAU,EAAE,IAAI,EAAE,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;IACrF,CAAC,IAAI,EAAE,aAAa,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;IAC9C,CAAC,IAAI,EAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAA;CACvD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,MAAM,WAAW,QAAQ;IACrB;;;;OAIG;IACH,cAAc,EAAE,CAAC,GAAG,SAAS,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,GAAG,CAAC,CAAA;IAElF;;;;OAIG;IACH,kBAAkB,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,KAAK,YAAY,CAAA;IAE1D;;;OAGG;IACH,cAAc,CAAC,GAAG,KAAK,WAAW,CAAC,GAAG,CAAC,CAAA;IAEvC;;;;;OAKG;IACH,YAAY,EAAE,OAAO,YAAY,CAAA;CACpC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,YAAY;IACzB;;;OAGG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAE/B;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAEhC;;;OAGG;IACH,mBAAmB,EAAE,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,KAAK,IAAI,CAAA;IAEtE;;;;;OAKG;IACH,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,mBAAmB,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,MAAM,CAAA;IAEjE;;;OAGG;IACH,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;IAE3F;;;OAGG;IACH,2BAA2B,EAAE,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,KAAK,IAAI,CAAA;IAE7E;;;OAGG;IACH,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IAE3C;;;OAGG;IACH,gBAAgB,EAAE,MAAM,MAAM,GAAG,IAAI,CAAA;IAErC;;;;OAIG;IACH,UAAU,EAAE,MAAM,OAAO,EAAE,CAAA;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,OAAO;IACpB,iGAAiG;IACjG,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;IACnC,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB;;;;OAIG;IACH,YAAY,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;KAAE,CAAA;IACzD;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,iGAAiG;IACjG,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,cAAc,CAAC,GAAG,GAAE,YAAiB,GAAG,QAAQ,CAyM/D;AA+ED,iBAAS,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAO9D;AAED,wBAAgB,kBAAkB,CAAC,eAAe,GAAE,OAAO,EAAO,GAAG,YAAY,CAiDhF;AAED,wBAAgB,cAAc,CAAC,GAAG,GAAG,OAAO,KAAK,WAAW,CAAC,GAAG,CAAC,CAEhE"}
|
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,79 +52,49 @@ function createAIEngine(cfg = {}) {
|
|
|
53
52
|
throw new Error('OpenAI API key is not set');
|
|
54
53
|
},
|
|
55
54
|
};
|
|
56
|
-
function createWorkflow({ onError }) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
};
|
|
66
|
-
const rewindTo = (step) => {
|
|
67
|
-
const index = steps.indexOf(step);
|
|
68
|
-
if (index === -1) {
|
|
69
|
-
throw new Error(`Step ${step.name} not found`);
|
|
70
|
-
}
|
|
71
|
-
if (index > currentStep) {
|
|
72
|
-
throw new Error(`Cannot rewind to a step ahead of the current step`);
|
|
73
|
-
}
|
|
74
|
-
currentStep = index - 1; // -1 because it will be incremented in the loop definition
|
|
75
|
-
};
|
|
76
|
-
const workflowControls = { terminate, rewindTo };
|
|
77
|
-
const workflow = {
|
|
78
|
-
terminate,
|
|
79
|
-
run: async (messages, ctx) => {
|
|
80
|
-
logger.debug('AI Engine: run workflow');
|
|
81
|
-
logger.debug('AI Engine conv prop reply: ' + messages.getProposedReply());
|
|
82
|
-
const random = Math.random().toString(36).substring(2, 8);
|
|
83
|
-
for (; currentStep < steps.length; currentStep++) {
|
|
84
|
-
logger.debug(random + ' ' + 'AI Engine conv prop reply at the start of the loop iteration: ' + messages.getProposedReply());
|
|
85
|
-
await beforeEachCallback();
|
|
86
|
-
logger.debug(random + ' ' + 'AI Engine conv prop reply after beforeEachCallback: ' + messages.getProposedReply());
|
|
87
|
-
const step = steps[currentStep];
|
|
88
|
-
logger.debug(random + ' ' + 'AI Engine step: ' + step.name);
|
|
89
|
-
if (!shouldRun) {
|
|
55
|
+
function createWorkflow({ onError, steps = [], }) {
|
|
56
|
+
steps.forEach(addStepToTracer);
|
|
57
|
+
return {
|
|
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()) {
|
|
90
64
|
logger.debug('AI Engine: run terminated');
|
|
91
65
|
break;
|
|
92
66
|
}
|
|
93
|
-
logger.debug('AI Engine conv prop reply passed to runif: ' + messages.getProposedReply());
|
|
94
67
|
if (!step.runIf || (await step.runIf(messages, ctx))) {
|
|
95
68
|
const action = (0, action_1.makeAction)(cfg.sendAction, 'AI', step.name);
|
|
96
69
|
await action('started');
|
|
97
70
|
logger.debug(`AI Engine: Step: ${step.name}`);
|
|
98
71
|
if ('prompt' in step) {
|
|
99
|
-
|
|
100
|
-
await runStep(step, messages, ctx, onError);
|
|
72
|
+
await runStep(step, messages, ctx, state);
|
|
101
73
|
}
|
|
102
74
|
else {
|
|
103
|
-
await runProgrammaticStep(step, messages, ctx);
|
|
75
|
+
await runProgrammaticStep(step, messages, ctx, state);
|
|
104
76
|
}
|
|
105
77
|
await action('completed');
|
|
106
78
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
currentStep = 0;
|
|
110
|
-
return shouldRun ? messages.getProposedReply() : null;
|
|
111
|
-
},
|
|
112
|
-
rewindTo,
|
|
113
|
-
beforeEach(callback) {
|
|
114
|
-
beforeEachCallback = callback;
|
|
79
|
+
} while (state.next());
|
|
80
|
+
return state.isTerminated() ? null : messages.getProposedReply();
|
|
115
81
|
},
|
|
116
82
|
addStep(step) {
|
|
117
|
-
|
|
118
|
-
tracer.addStep({
|
|
119
|
-
name: step.name,
|
|
120
|
-
prompt: (0, tracer_1.stdPrompt)(step.prompt),
|
|
121
|
-
type: 'text',
|
|
122
|
-
schema: 'schema' in step ? step.schema : undefined,
|
|
123
|
-
});
|
|
124
|
-
}
|
|
83
|
+
addStepToTracer(step);
|
|
125
84
|
steps.push(step);
|
|
126
85
|
},
|
|
127
86
|
};
|
|
128
|
-
|
|
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) {
|
|
129
98
|
if (!apiKey) {
|
|
130
99
|
apiKey = await tokenStorage.getToken();
|
|
131
100
|
}
|
|
@@ -150,7 +119,6 @@ function createAIEngine(cfg = {}) {
|
|
|
150
119
|
logger.debug('AI Engine: messages', conversation.toString({ ignoreAddedMessages: step.ignoreAddedMessages }));
|
|
151
120
|
prompt = renderPrompt(prompt, ctx);
|
|
152
121
|
stepTrace.renderedPrompt = prompt;
|
|
153
|
-
logger.debug('AI Engine conv prop reply in runStep: ' + conversation.getProposedReply());
|
|
154
122
|
const stringifiedMessages = conversation.toString({
|
|
155
123
|
ignoreAddedMessages: step.ignoreAddedMessages,
|
|
156
124
|
});
|
|
@@ -167,22 +135,8 @@ function createAIEngine(cfg = {}) {
|
|
|
167
135
|
if (!response) {
|
|
168
136
|
throw new Error('No response from OpenAI');
|
|
169
137
|
}
|
|
170
|
-
logger.debug(`AI Engine: response
|
|
171
|
-
|
|
172
|
-
if (await step.shouldExecute(response, ctx)) {
|
|
173
|
-
logger.debug(`AI Engine: executing`);
|
|
174
|
-
checkAttempts(step);
|
|
175
|
-
await step.execute(response, conversation, ctx, workflowControls);
|
|
176
|
-
}
|
|
177
|
-
else {
|
|
178
|
-
resetAttempts(step);
|
|
179
|
-
logger.debug(`AI Engine: skipping`);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
else {
|
|
183
|
-
logger.debug(`AI Engine: replying`);
|
|
184
|
-
await step.execute(response, conversation, ctx, workflowControls);
|
|
185
|
-
}
|
|
138
|
+
logger.debug(`AI Engine: executing ${step.name}, LLM response`, response);
|
|
139
|
+
await step.execute(response, conversation, ctx, state);
|
|
186
140
|
}
|
|
187
141
|
catch (error) {
|
|
188
142
|
await (step.onError
|
|
@@ -190,38 +144,23 @@ function createAIEngine(cfg = {}) {
|
|
|
190
144
|
: onError(error.message, ctx));
|
|
191
145
|
// FIXME: this doesn't terminate the workflow
|
|
192
146
|
stepTracer?.addStepTrace(stepTrace);
|
|
193
|
-
|
|
147
|
+
state.terminate();
|
|
194
148
|
}
|
|
195
149
|
}
|
|
196
|
-
async function runProgrammaticStep(step, messages, ctx) {
|
|
150
|
+
async function runProgrammaticStep(step, messages, ctx, state) {
|
|
197
151
|
try {
|
|
198
152
|
if (!step.runIf || (await step.runIf(messages, ctx))) {
|
|
199
|
-
await step.execute(messages, ctx);
|
|
153
|
+
await step.execute(messages, ctx, state);
|
|
200
154
|
}
|
|
201
155
|
}
|
|
202
156
|
catch (error) {
|
|
203
|
-
|
|
157
|
+
logger.error(`AI Engine: error in dumb step ${step.name}: ${error.message}`);
|
|
204
158
|
await (step.onError
|
|
205
159
|
? step.onError(error.message, ctx)
|
|
206
160
|
: onError(error.message, ctx));
|
|
207
|
-
|
|
161
|
+
state.terminate();
|
|
208
162
|
}
|
|
209
163
|
}
|
|
210
|
-
function checkAttempts(step) {
|
|
211
|
-
if (step.maxAttempts) {
|
|
212
|
-
if (!attempts.has(step)) {
|
|
213
|
-
attempts.set(step, 0);
|
|
214
|
-
}
|
|
215
|
-
attempts.set(step, attempts.get(step) + 1);
|
|
216
|
-
if (attempts.get(step) > step.maxAttempts) {
|
|
217
|
-
throw new Error(`Max attempts reached for step ${step.name}`);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
function resetAttempts(step) {
|
|
222
|
-
attempts.set(step, 0);
|
|
223
|
-
}
|
|
224
|
-
return workflow;
|
|
225
164
|
}
|
|
226
165
|
async function runLLM(apiKey, systemPrompt, messages, schema, model = 'gpt-4o-2024-08-06') {
|
|
227
166
|
logger.debug('AI Engine: model:', model);
|
|
@@ -235,7 +174,7 @@ function createAIEngine(cfg = {}) {
|
|
|
235
174
|
}
|
|
236
175
|
return JSON.stringify({ message: 'canned response', reasons: [] });
|
|
237
176
|
}
|
|
238
|
-
const client = new openai_1.
|
|
177
|
+
const client = new openai_1.OpenAI({ apiKey });
|
|
239
178
|
const response = await client.chat.completions.create({
|
|
240
179
|
messages: [
|
|
241
180
|
{ role: 'system', content: systemPrompt },
|
|
@@ -257,6 +196,54 @@ function createAIEngine(cfg = {}) {
|
|
|
257
196
|
},
|
|
258
197
|
};
|
|
259
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
|
+
}
|
|
260
247
|
function getOpenAiOptions(model, schema) {
|
|
261
248
|
const options = {
|
|
262
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
|
+
}
|
|
@@ -3,7 +3,7 @@ import { PromptFile } from '../prompt-fs';
|
|
|
3
3
|
export type StepTrace = {
|
|
4
4
|
name: string;
|
|
5
5
|
renderedPrompt?: string;
|
|
6
|
-
receivedContext?:
|
|
6
|
+
receivedContext?: unknown;
|
|
7
7
|
receivedPrompt?: string | PromptFile;
|
|
8
8
|
stringifiedConversation?: string;
|
|
9
9
|
schema?: ZodSchema;
|
|
@@ -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;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,
|
|
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.8.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
|