@codemation/core-nodes 0.2.0 → 0.4.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/CHANGELOG.md +23 -1
- package/dist/index.cjs +10 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -30
- package/dist/index.d.ts +42 -30
- package/dist/index.js +11 -11
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/nodes/AIAgentNode.ts +1 -1
- package/src/nodes/NodeBackedToolRuntime.ts +4 -4
- package/src/workflowAuthoring/WorkflowBranchBuilder.types.ts +19 -14
- package/src/workflowAuthoring/WorkflowChain.types.ts +39 -25
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codemation/core-nodes",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@langchain/core": "^1.1.31",
|
|
32
32
|
"@langchain/openai": "^1.2.12",
|
|
33
33
|
"lucide-react": "^0.577.0",
|
|
34
|
-
"@codemation/core": "0.
|
|
34
|
+
"@codemation/core": "0.7.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/node": "^25.3.5",
|
package/src/nodes/AIAgentNode.ts
CHANGED
|
@@ -68,7 +68,7 @@ export class AIAgentNode implements RunnableNode<AIAgent<any, any>> {
|
|
|
68
68
|
outputPorts = ["main"] as const;
|
|
69
69
|
/**
|
|
70
70
|
* Engine validates {@link RunnableNodeConfig.inputSchema} (Zod) on {@code item.json} before enqueue, then resolves
|
|
71
|
-
* per-item **`
|
|
71
|
+
* per-item **`itemExpr`** leaves on config before {@link #execute}. Prefer modeling prompts as
|
|
72
72
|
* {@code { messages: [{ role, content }, ...] }} (on input or config) so persisted inputs are visible in the UI.
|
|
73
73
|
*/
|
|
74
74
|
readonly inputSchema = z.unknown();
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
CoreTokens,
|
|
15
15
|
inject,
|
|
16
16
|
injectable,
|
|
17
|
-
|
|
17
|
+
ItemExprResolver,
|
|
18
18
|
NodeOutputNormalizer,
|
|
19
19
|
RunnableOutputBehaviorResolver,
|
|
20
20
|
} from "@codemation/core";
|
|
@@ -25,8 +25,8 @@ export class NodeBackedToolRuntime {
|
|
|
25
25
|
constructor(
|
|
26
26
|
@inject(CoreTokens.NodeResolver)
|
|
27
27
|
private readonly nodeResolver: NodeResolver,
|
|
28
|
-
@inject(
|
|
29
|
-
private readonly
|
|
28
|
+
@inject(ItemExprResolver)
|
|
29
|
+
private readonly itemExprResolver: ItemExprResolver,
|
|
30
30
|
@inject(NodeOutputNormalizer)
|
|
31
31
|
private readonly outputNormalizer: NodeOutputNormalizer,
|
|
32
32
|
@inject(RunnableOutputBehaviorResolver)
|
|
@@ -77,7 +77,7 @@ export class NodeBackedToolRuntime {
|
|
|
77
77
|
const inputSchema = runnable.inputSchema ?? runnableConfig.inputSchema ?? z.unknown();
|
|
78
78
|
const parsed = inputSchema.parse(nodeInput.json);
|
|
79
79
|
const items = [nodeInput];
|
|
80
|
-
const resolvedCtx = await this.
|
|
80
|
+
const resolvedCtx = await this.itemExprResolver.resolveConfigForItem(ctx, nodeInput, 0, items);
|
|
81
81
|
const execArgs: RunnableNodeExecuteArgs = {
|
|
82
82
|
input: parsed,
|
|
83
83
|
item: nodeInput,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AnyRunnableNodeConfig,
|
|
3
|
+
CredentialJsonRecord,
|
|
3
4
|
DefinedNode,
|
|
5
|
+
DefinedNodeConfigInput,
|
|
4
6
|
Item,
|
|
5
7
|
Items,
|
|
6
8
|
NodeExecutionContext,
|
|
@@ -19,6 +21,11 @@ import { WorkflowAgentNodeFactory } from "./WorkflowAgentNodeFactory.types";
|
|
|
19
21
|
import { WorkflowDefinedNodeResolver } from "./WorkflowDefinedNodeResolver.types";
|
|
20
22
|
import { WorkflowDurationParser } from "./WorkflowDurationParser.types";
|
|
21
23
|
|
|
24
|
+
type WorkflowMapCallback<TCurrentJson, TNextJson> = (
|
|
25
|
+
item: Item<TCurrentJson>,
|
|
26
|
+
ctx: NodeExecutionContext<MapData<TCurrentJson, TNextJson>>,
|
|
27
|
+
) => TNextJson;
|
|
28
|
+
|
|
22
29
|
export class WorkflowBranchBuilder<TCurrentJson> {
|
|
23
30
|
constructor(private readonly steps: ReadonlyArray<AnyRunnableNodeConfig> = []) {}
|
|
24
31
|
|
|
@@ -28,22 +35,20 @@ export class WorkflowBranchBuilder<TCurrentJson> {
|
|
|
28
35
|
return new WorkflowBranchBuilder<RunnableNodeOutputJson<TConfig>>([...this.steps, config]);
|
|
29
36
|
}
|
|
30
37
|
|
|
31
|
-
map<TNextJson>(mapper:
|
|
38
|
+
map<TNextJson>(mapper: WorkflowMapCallback<TCurrentJson, TNextJson>): WorkflowBranchBuilder<TNextJson>;
|
|
32
39
|
map<TNextJson>(
|
|
33
40
|
name: string,
|
|
34
|
-
mapper:
|
|
41
|
+
mapper: WorkflowMapCallback<TCurrentJson, TNextJson>,
|
|
35
42
|
options?: MapDataOptions,
|
|
36
43
|
): WorkflowBranchBuilder<TNextJson>;
|
|
37
44
|
map<TNextJson>(
|
|
38
|
-
nameOrMapper: string |
|
|
39
|
-
mapperOrUndefined?:
|
|
45
|
+
nameOrMapper: string | WorkflowMapCallback<TCurrentJson, TNextJson>,
|
|
46
|
+
mapperOrUndefined?: WorkflowMapCallback<TCurrentJson, TNextJson>,
|
|
40
47
|
options?: MapDataOptions,
|
|
41
48
|
): WorkflowBranchBuilder<TNextJson> {
|
|
42
49
|
const name = typeof nameOrMapper === "string" ? nameOrMapper : "Map data";
|
|
43
50
|
const mapper = typeof nameOrMapper === "string" ? mapperOrUndefined! : nameOrMapper;
|
|
44
|
-
return this.then(
|
|
45
|
-
new MapData<TCurrentJson, TNextJson>(name, (item) => mapper(item.json as TCurrentJson), options),
|
|
46
|
-
) as WorkflowBranchBuilder<TNextJson>;
|
|
51
|
+
return this.then(new MapData<TCurrentJson, TNextJson>(name, mapper, options)) as WorkflowBranchBuilder<TNextJson>;
|
|
47
52
|
}
|
|
48
53
|
|
|
49
54
|
wait(duration: number | string): WorkflowBranchBuilder<TCurrentJson>;
|
|
@@ -172,18 +177,18 @@ export class WorkflowBranchBuilder<TCurrentJson> {
|
|
|
172
177
|
>;
|
|
173
178
|
}
|
|
174
179
|
|
|
175
|
-
node<TConfig extends
|
|
176
|
-
definitionOrKey: DefinedNode<string, TConfig,
|
|
177
|
-
config: TConfig,
|
|
180
|
+
node<TConfig extends CredentialJsonRecord, TInputJson, TOutputJson>(
|
|
181
|
+
definitionOrKey: DefinedNode<string, TConfig, TInputJson, TOutputJson> | string,
|
|
182
|
+
config: DefinedNodeConfigInput<TConfig, TCurrentJson>,
|
|
178
183
|
name?: string,
|
|
179
184
|
id?: string,
|
|
180
|
-
): WorkflowBranchBuilder<TOutputJson> {
|
|
185
|
+
): TCurrentJson extends TInputJson ? WorkflowBranchBuilder<TOutputJson> : never {
|
|
181
186
|
const definition = WorkflowDefinedNodeResolver.resolve(
|
|
182
187
|
definitionOrKey as DefinedNode<string, Record<string, unknown>, unknown, unknown> | string,
|
|
183
|
-
) as DefinedNode<string, TConfig,
|
|
188
|
+
) as DefinedNode<string, TConfig, TInputJson, TOutputJson>;
|
|
184
189
|
return this.then(
|
|
185
|
-
definition.create(config, name, id) as RunnableNodeConfig<TCurrentJson, TOutputJson>,
|
|
186
|
-
) as WorkflowBranchBuilder<TOutputJson
|
|
190
|
+
definition.create(config, name, id) as unknown as RunnableNodeConfig<TCurrentJson, TOutputJson>,
|
|
191
|
+
) as TCurrentJson extends TInputJson ? WorkflowBranchBuilder<TOutputJson> : never;
|
|
187
192
|
}
|
|
188
193
|
|
|
189
194
|
getSteps(): ReadonlyArray<AnyRunnableNodeConfig> {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
CredentialJsonRecord,
|
|
2
3
|
DefinedNode,
|
|
4
|
+
DefinedNodeConfigInput,
|
|
3
5
|
Item,
|
|
4
6
|
Items,
|
|
5
7
|
NodeExecutionContext,
|
|
@@ -29,6 +31,18 @@ type BranchCallback<TCurrentJson, TNextJson> = (
|
|
|
29
31
|
) => WorkflowBranchBuilder<TNextJson>;
|
|
30
32
|
type RouteBranchCallback<TCurrentJson, TNextJson> = (branch: WorkflowChain<TCurrentJson>) => WorkflowChain<TNextJson>;
|
|
31
33
|
type BranchOutputMatch<TLeft, TRight> = [TLeft] extends [TRight] ? ([TRight] extends [TLeft] ? true : false) : false;
|
|
34
|
+
type WorkflowMapCallback<TCurrentJson, TNextJson> = (
|
|
35
|
+
item: Item<TCurrentJson>,
|
|
36
|
+
ctx: NodeExecutionContext<MapData<TCurrentJson, TNextJson>>,
|
|
37
|
+
) => TNextJson;
|
|
38
|
+
type WorkflowIfPredicate<TCurrentJson> = (
|
|
39
|
+
item: Item<TCurrentJson>,
|
|
40
|
+
ctx: NodeExecutionContext<If<TCurrentJson>>,
|
|
41
|
+
) => boolean;
|
|
42
|
+
type WorkflowSwitchCaseKeyResolver<TCurrentJson> = (
|
|
43
|
+
item: Item<TCurrentJson>,
|
|
44
|
+
ctx: NodeExecutionContext<Switch<TCurrentJson>>,
|
|
45
|
+
) => string | Promise<string>;
|
|
32
46
|
|
|
33
47
|
export class WorkflowChain<TCurrentJson> {
|
|
34
48
|
constructor(private readonly chain: ChainCursor<TCurrentJson>) {}
|
|
@@ -39,22 +53,20 @@ export class WorkflowChain<TCurrentJson> {
|
|
|
39
53
|
return new WorkflowChain(this.chain.then(config));
|
|
40
54
|
}
|
|
41
55
|
|
|
42
|
-
map<TNextJson>(mapper:
|
|
56
|
+
map<TNextJson>(mapper: WorkflowMapCallback<TCurrentJson, TNextJson>): WorkflowChain<TNextJson>;
|
|
43
57
|
map<TNextJson>(
|
|
44
58
|
name: string,
|
|
45
|
-
mapper:
|
|
59
|
+
mapper: WorkflowMapCallback<TCurrentJson, TNextJson>,
|
|
46
60
|
options?: MapDataOptions,
|
|
47
61
|
): WorkflowChain<TNextJson>;
|
|
48
62
|
map<TNextJson>(
|
|
49
|
-
nameOrMapper: string |
|
|
50
|
-
mapperOrUndefined?:
|
|
63
|
+
nameOrMapper: string | WorkflowMapCallback<TCurrentJson, TNextJson>,
|
|
64
|
+
mapperOrUndefined?: WorkflowMapCallback<TCurrentJson, TNextJson>,
|
|
51
65
|
options?: MapDataOptions,
|
|
52
66
|
): WorkflowChain<TNextJson> {
|
|
53
67
|
const name = typeof nameOrMapper === "string" ? nameOrMapper : "Map data";
|
|
54
68
|
const mapper = typeof nameOrMapper === "string" ? mapperOrUndefined! : nameOrMapper;
|
|
55
|
-
return this.then(
|
|
56
|
-
new MapData<TCurrentJson, TNextJson>(name, (item) => mapper(item.json as TCurrentJson), options),
|
|
57
|
-
) as WorkflowChain<TNextJson>;
|
|
69
|
+
return this.then(new MapData<TCurrentJson, TNextJson>(name, mapper, options)) as WorkflowChain<TNextJson>;
|
|
58
70
|
}
|
|
59
71
|
|
|
60
72
|
wait(duration: number | string): WorkflowChain<TCurrentJson>;
|
|
@@ -190,7 +202,7 @@ export class WorkflowChain<TCurrentJson> {
|
|
|
190
202
|
}
|
|
191
203
|
|
|
192
204
|
if<TBranchJson>(
|
|
193
|
-
predicate:
|
|
205
|
+
predicate: WorkflowIfPredicate<TCurrentJson>,
|
|
194
206
|
branches: Readonly<{
|
|
195
207
|
true?: BranchCallback<TCurrentJson, TBranchJson>;
|
|
196
208
|
false?: BranchCallback<TCurrentJson, TBranchJson>;
|
|
@@ -198,16 +210,16 @@ export class WorkflowChain<TCurrentJson> {
|
|
|
198
210
|
): WorkflowChain<TBranchJson>;
|
|
199
211
|
if<TBranchJson>(
|
|
200
212
|
name: string,
|
|
201
|
-
predicate:
|
|
213
|
+
predicate: WorkflowIfPredicate<TCurrentJson>,
|
|
202
214
|
branches: Readonly<{
|
|
203
215
|
true?: BranchCallback<TCurrentJson, TBranchJson>;
|
|
204
216
|
false?: BranchCallback<TCurrentJson, TBranchJson>;
|
|
205
217
|
}>,
|
|
206
218
|
): WorkflowChain<TBranchJson>;
|
|
207
219
|
if<TTrueJson, TFalseJson>(
|
|
208
|
-
nameOrPredicate: string |
|
|
220
|
+
nameOrPredicate: string | WorkflowIfPredicate<TCurrentJson>,
|
|
209
221
|
predicateOrBranches:
|
|
210
|
-
|
|
|
222
|
+
| WorkflowIfPredicate<TCurrentJson>
|
|
211
223
|
| Readonly<{ true?: BranchCallback<TCurrentJson, TTrueJson>; false?: BranchCallback<TCurrentJson, TFalseJson> }>,
|
|
212
224
|
branchesOrUndefined?: Readonly<{
|
|
213
225
|
true?: BranchCallback<TCurrentJson, TTrueJson>;
|
|
@@ -216,12 +228,14 @@ export class WorkflowChain<TCurrentJson> {
|
|
|
216
228
|
): WorkflowChain<BranchOutputMatch<TTrueJson, TFalseJson> extends true ? TTrueJson : never> {
|
|
217
229
|
const name = typeof nameOrPredicate === "string" ? nameOrPredicate : "If";
|
|
218
230
|
const predicate =
|
|
219
|
-
typeof nameOrPredicate === "string"
|
|
231
|
+
typeof nameOrPredicate === "string"
|
|
232
|
+
? (predicateOrBranches as WorkflowIfPredicate<TCurrentJson>)
|
|
233
|
+
: nameOrPredicate;
|
|
220
234
|
const branches = (typeof nameOrPredicate === "string" ? branchesOrUndefined : predicateOrBranches) as Readonly<{
|
|
221
235
|
true?: BranchCallback<TCurrentJson, TTrueJson>;
|
|
222
236
|
false?: BranchCallback<TCurrentJson, TFalseJson>;
|
|
223
237
|
}>;
|
|
224
|
-
const cursor = this.chain.then(new If<TCurrentJson>(name, (item) => predicate(item
|
|
238
|
+
const cursor = this.chain.then(new If<TCurrentJson>(name, (item, _index, _items, ctx) => predicate(item, ctx)));
|
|
225
239
|
const trueSteps = branches.true?.(new WorkflowBranchBuilder<TCurrentJson>()).getSteps();
|
|
226
240
|
const falseSteps = branches.false?.(new WorkflowBranchBuilder<TCurrentJson>()).getSteps();
|
|
227
241
|
return new WorkflowChain(
|
|
@@ -258,7 +272,7 @@ export class WorkflowChain<TCurrentJson> {
|
|
|
258
272
|
cfg: Readonly<{
|
|
259
273
|
cases: readonly string[];
|
|
260
274
|
defaultCase: string;
|
|
261
|
-
resolveCaseKey:
|
|
275
|
+
resolveCaseKey: WorkflowSwitchCaseKeyResolver<TCurrentJson>;
|
|
262
276
|
branches: Readonly<Record<string, RouteBranchCallback<TCurrentJson, TBranchJson> | undefined>>;
|
|
263
277
|
}>,
|
|
264
278
|
): WorkflowChain<TBranchJson>;
|
|
@@ -267,7 +281,7 @@ export class WorkflowChain<TCurrentJson> {
|
|
|
267
281
|
cfg: Readonly<{
|
|
268
282
|
cases: readonly string[];
|
|
269
283
|
defaultCase: string;
|
|
270
|
-
resolveCaseKey:
|
|
284
|
+
resolveCaseKey: WorkflowSwitchCaseKeyResolver<TCurrentJson>;
|
|
271
285
|
branches: Readonly<Record<string, RouteBranchCallback<TCurrentJson, TBranchJson> | undefined>>;
|
|
272
286
|
}>,
|
|
273
287
|
id?: string,
|
|
@@ -278,13 +292,13 @@ export class WorkflowChain<TCurrentJson> {
|
|
|
278
292
|
| Readonly<{
|
|
279
293
|
cases: readonly string[];
|
|
280
294
|
defaultCase: string;
|
|
281
|
-
resolveCaseKey:
|
|
295
|
+
resolveCaseKey: WorkflowSwitchCaseKeyResolver<TCurrentJson>;
|
|
282
296
|
branches: Readonly<Record<string, RouteBranchCallback<TCurrentJson, TBranchJson> | undefined>>;
|
|
283
297
|
}>,
|
|
284
298
|
cfgOrUndefined?: Readonly<{
|
|
285
299
|
cases: readonly string[];
|
|
286
300
|
defaultCase: string;
|
|
287
|
-
resolveCaseKey:
|
|
301
|
+
resolveCaseKey: WorkflowSwitchCaseKeyResolver<TCurrentJson>;
|
|
288
302
|
branches: Readonly<Record<string, RouteBranchCallback<TCurrentJson, TBranchJson> | undefined>>;
|
|
289
303
|
}>,
|
|
290
304
|
id?: string,
|
|
@@ -297,7 +311,7 @@ export class WorkflowChain<TCurrentJson> {
|
|
|
297
311
|
{
|
|
298
312
|
cases: cfg.cases,
|
|
299
313
|
defaultCase: cfg.defaultCase,
|
|
300
|
-
resolveCaseKey: (item) => cfg.resolveCaseKey(item
|
|
314
|
+
resolveCaseKey: (item, _index, _items, ctx) => cfg.resolveCaseKey(item, ctx),
|
|
301
315
|
},
|
|
302
316
|
id,
|
|
303
317
|
),
|
|
@@ -322,18 +336,18 @@ export class WorkflowChain<TCurrentJson> {
|
|
|
322
336
|
>;
|
|
323
337
|
}
|
|
324
338
|
|
|
325
|
-
node<TConfig extends
|
|
326
|
-
definitionOrKey: DefinedNode<string, TConfig,
|
|
327
|
-
config: TConfig,
|
|
339
|
+
node<TConfig extends CredentialJsonRecord, TInputJson, TOutputJson>(
|
|
340
|
+
definitionOrKey: DefinedNode<string, TConfig, TInputJson, TOutputJson> | string,
|
|
341
|
+
config: DefinedNodeConfigInput<TConfig, TCurrentJson>,
|
|
328
342
|
name?: string,
|
|
329
343
|
id?: string,
|
|
330
|
-
): WorkflowChain<TOutputJson> {
|
|
344
|
+
): TCurrentJson extends TInputJson ? WorkflowChain<TOutputJson> : never {
|
|
331
345
|
const definition = WorkflowDefinedNodeResolver.resolve(
|
|
332
346
|
definitionOrKey as DefinedNode<string, Record<string, unknown>, unknown, unknown> | string,
|
|
333
|
-
) as DefinedNode<string, TConfig,
|
|
347
|
+
) as DefinedNode<string, TConfig, TInputJson, TOutputJson>;
|
|
334
348
|
return this.then(
|
|
335
|
-
definition.create(config, name, id) as RunnableNodeConfig<TCurrentJson, TOutputJson>,
|
|
336
|
-
) as WorkflowChain<TOutputJson
|
|
349
|
+
definition.create(config, name, id) as unknown as RunnableNodeConfig<TCurrentJson, TOutputJson>,
|
|
350
|
+
) as TCurrentJson extends TInputJson ? WorkflowChain<TOutputJson> : never;
|
|
337
351
|
}
|
|
338
352
|
|
|
339
353
|
build(): WorkflowDefinition {
|