@codemation/core-nodes 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.
Files changed (53) hide show
  1. package/CHANGELOG.md +203 -0
  2. package/LICENSE +1 -37
  3. package/dist/index.cjs +957 -70
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.cts +527 -61
  6. package/dist/index.d.ts +527 -61
  7. package/dist/index.js +936 -69
  8. package/dist/index.js.map +1 -1
  9. package/dist/metadata.json +162 -0
  10. package/package.json +4 -3
  11. package/src/authoring/defineRestNode.types.ts +17 -2
  12. package/src/chatModels/CodemationChatModelConfig.ts +47 -0
  13. package/src/chatModels/CodemationChatModelFactory.ts +103 -0
  14. package/src/chatModels/ManagedModelFetcher.ts +23 -0
  15. package/src/http/HttpRequestExecutor.ts +10 -2
  16. package/src/http/SSRFBlockedError.ts +16 -0
  17. package/src/http/SsrfGuard.ts +141 -0
  18. package/src/http/httpRequest.types.ts +6 -0
  19. package/src/index.ts +4 -0
  20. package/src/nodes/AIAgentConfig.ts +66 -0
  21. package/src/nodes/AIAgentNode.ts +205 -27
  22. package/src/nodes/BM25Index.ts +90 -0
  23. package/src/nodes/CallbackNodeFactory.ts +7 -0
  24. package/src/nodes/CronTriggerFactory.ts +9 -1
  25. package/src/nodes/DeferredMetaToolStrategy.ts +200 -0
  26. package/src/nodes/DeferredMetaToolStrategyFactory.ts +18 -0
  27. package/src/nodes/HttpRequestNodeFactory.ts +10 -3
  28. package/src/nodes/ManualTriggerFactory.ts +16 -1
  29. package/src/nodes/ToolLoadingStrategy.ts +28 -0
  30. package/src/nodes/WebhookTriggerFactory.ts +16 -2
  31. package/src/nodes/aggregate.ts +13 -2
  32. package/src/nodes/aiAgent.ts +9 -0
  33. package/src/nodes/assertion.ts +14 -1
  34. package/src/nodes/collections/collectionDeleteNode.types.ts +6 -0
  35. package/src/nodes/collections/collectionFindOneNode.types.ts +6 -0
  36. package/src/nodes/collections/collectionGetNode.types.ts +6 -0
  37. package/src/nodes/collections/collectionInsertNode.types.ts +6 -0
  38. package/src/nodes/collections/collectionListNode.types.ts +6 -0
  39. package/src/nodes/collections/collectionUpdateNode.types.ts +6 -0
  40. package/src/nodes/filter.ts +14 -2
  41. package/src/nodes/httpRequest.ts +72 -8
  42. package/src/nodes/if.ts +14 -2
  43. package/src/nodes/mapData.ts +13 -2
  44. package/src/nodes/merge.ts +9 -2
  45. package/src/nodes/noOp.ts +0 -1
  46. package/src/nodes/split.ts +13 -2
  47. package/src/nodes/subWorkflow.ts +15 -2
  48. package/src/nodes/switch.ts +18 -2
  49. package/src/nodes/testTrigger.ts +13 -0
  50. package/src/nodes/wait.ts +7 -1
  51. package/src/workflowAuthoring/WorkflowChatModelFactory.types.ts +4 -0
  52. package/src/workflows/AIAgentConnectionWorkflowExpander.ts +6 -3
  53. package/tsconfig.json +3 -1
@@ -1,5 +1,10 @@
1
- import type { Item, NodeExecutionContext, RunnableNodeConfig, TypeToken } from "@codemation/core";
2
-
1
+ import type {
2
+ Item,
3
+ NodeExecutionContext,
4
+ NodeInspectorSummaryRow,
5
+ RunnableNodeConfig,
6
+ TypeToken,
7
+ } from "@codemation/core";
3
8
  import { MapDataNode } from "./MapDataNode";
4
9
 
5
10
  export interface MapDataOptions {
@@ -33,6 +38,12 @@ export class MapData<TInputJson = unknown, TOutputJson = unknown> implements Run
33
38
  get id(): string | undefined {
34
39
  return this.options.id;
35
40
  }
41
+
42
+ inspectorSummary(): ReadonlyArray<NodeInspectorSummaryRow> | undefined {
43
+ const fnName = this.map.name;
44
+ if (!fnName) return undefined;
45
+ return [{ label: "Mapper", value: fnName }];
46
+ }
36
47
  }
37
48
 
38
49
  export { MapDataNode } from "./MapDataNode";
@@ -1,5 +1,4 @@
1
- import type { InputPortKey, RunnableNodeConfig, TypeToken } from "@codemation/core";
2
-
1
+ import type { InputPortKey, NodeInspectorSummaryRow, RunnableNodeConfig, TypeToken } from "@codemation/core";
3
2
  import { MergeNode } from "./MergeNode";
4
3
 
5
4
  export type MergeMode = "passThrough" | "append" | "mergeByPosition";
@@ -24,6 +23,14 @@ export class Merge<TInputJson = unknown, TOutputJson = TInputJson> implements Ru
24
23
  }> = { mode: "passThrough" },
25
24
  public readonly id?: string,
26
25
  ) {}
26
+
27
+ inspectorSummary(): ReadonlyArray<NodeInspectorSummaryRow> {
28
+ const rows: NodeInspectorSummaryRow[] = [{ label: "Mode", value: this.cfg.mode }];
29
+ if (this.cfg.prefer && this.cfg.prefer.length > 0) {
30
+ rows.push({ label: "Input order", value: this.cfg.prefer.join(", ").slice(0, 80) });
31
+ }
32
+ return rows;
33
+ }
27
34
  }
28
35
 
29
36
  export { MergeNode } from "./MergeNode";
package/src/nodes/noOp.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import type { RunnableNodeConfig, TypeToken } from "@codemation/core";
2
-
3
2
  import { NoOpNode } from "./NoOpNode";
4
3
 
5
4
  export class NoOp<TItemJson = unknown> implements RunnableNodeConfig<TItemJson, TItemJson> {
@@ -1,5 +1,10 @@
1
- import type { Item, NodeExecutionContext, RunnableNodeConfig, TypeToken } from "@codemation/core";
2
-
1
+ import type {
2
+ Item,
3
+ NodeExecutionContext,
4
+ NodeInspectorSummaryRow,
5
+ RunnableNodeConfig,
6
+ TypeToken,
7
+ } from "@codemation/core";
3
8
  import { SplitNode } from "./SplitNode";
4
9
 
5
10
  export class Split<TIn = unknown, TElem = unknown> implements RunnableNodeConfig<TIn, TElem> {
@@ -19,6 +24,12 @@ export class Split<TIn = unknown, TElem = unknown> implements RunnableNodeConfig
19
24
  public readonly getElements: (item: Item<TIn>, ctx: NodeExecutionContext<Split<TIn, TElem>>) => readonly TElem[],
20
25
  public readonly id?: string,
21
26
  ) {}
27
+
28
+ inspectorSummary(): ReadonlyArray<NodeInspectorSummaryRow> | undefined {
29
+ const fnName = this.getElements.name;
30
+ if (!fnName) return undefined;
31
+ return [{ label: "Split by", value: fnName }];
32
+ }
22
33
  }
23
34
 
24
35
  export { SplitNode } from "./SplitNode";
@@ -1,5 +1,10 @@
1
- import type { NodeId, RunnableNodeConfig, TypeToken, UpstreamRefPlaceholder } from "@codemation/core";
2
-
1
+ import type {
2
+ NodeId,
3
+ NodeInspectorSummaryRow,
4
+ RunnableNodeConfig,
5
+ TypeToken,
6
+ UpstreamRefPlaceholder,
7
+ } from "@codemation/core";
3
8
  import { SubWorkflowNode } from "./SubWorkflowNode";
4
9
 
5
10
  export class SubWorkflow<TInputJson = unknown, TOutputJson = unknown> implements RunnableNodeConfig<
@@ -16,6 +21,14 @@ export class SubWorkflow<TInputJson = unknown, TOutputJson = unknown> implements
16
21
  public readonly startAt?: NodeId,
17
22
  public readonly id?: string,
18
23
  ) {}
24
+
25
+ inspectorSummary(): ReadonlyArray<NodeInspectorSummaryRow> {
26
+ const rows: NodeInspectorSummaryRow[] = [{ label: "Workflow", value: this.workflowId }];
27
+ if (this.startAt) {
28
+ rows.push({ label: "Start at", value: this.startAt });
29
+ }
30
+ return rows;
31
+ }
19
32
  }
20
33
 
21
34
  export { SubWorkflowNode } from "./SubWorkflowNode";
@@ -1,5 +1,11 @@
1
- import type { Item, Items, NodeExecutionContext, RunnableNodeConfig, TypeToken } from "@codemation/core";
2
-
1
+ import type {
2
+ Item,
3
+ Items,
4
+ NodeExecutionContext,
5
+ NodeInspectorSummaryRow,
6
+ RunnableNodeConfig,
7
+ TypeToken,
8
+ } from "@codemation/core";
3
9
  import { SwitchNode } from "./SwitchNode";
4
10
 
5
11
  export type SwitchCaseKeyResolver<TInputJson = unknown> = (
@@ -27,6 +33,16 @@ export class Switch<TInputJson = unknown> implements RunnableNodeConfig<TInputJs
27
33
  ) {
28
34
  this.declaredOutputPorts = [...new Set([...cfg.cases, cfg.defaultCase])].sort();
29
35
  }
36
+
37
+ inspectorSummary(): ReadonlyArray<NodeInspectorSummaryRow> {
38
+ const rows: NodeInspectorSummaryRow[] = [
39
+ { label: "Cases", value: this.cfg.cases.join(", ").slice(0, 80) || "(none)" },
40
+ ];
41
+ if (this.cfg.defaultCase) {
42
+ rows.push({ label: "Default", value: this.cfg.defaultCase });
43
+ }
44
+ return rows;
45
+ }
30
46
  }
31
47
 
32
48
  export { SwitchNode } from "./SwitchNode";
@@ -1,6 +1,7 @@
1
1
  import type {
2
2
  CredentialRequirement,
3
3
  Item,
4
+ NodeInspectorSummaryRow,
4
5
  TestTriggerNodeConfig,
5
6
  TestTriggerSetupContext,
6
7
  TypeToken,
@@ -67,6 +68,18 @@ export class TestTrigger<TOutputJson = unknown> implements TestTriggerNodeConfig
67
68
  getCredentialRequirements(): ReadonlyArray<CredentialRequirement> {
68
69
  return this.credentialRequirements;
69
70
  }
71
+
72
+ inspectorSummary(): ReadonlyArray<NodeInspectorSummaryRow> | undefined {
73
+ const rows: NodeInspectorSummaryRow[] = [];
74
+ if (this.description) {
75
+ const desc = this.description.length > 80 ? `${this.description.slice(0, 79)}…` : this.description;
76
+ rows.push({ label: "Description", value: desc });
77
+ }
78
+ if (this.concurrency !== undefined) {
79
+ rows.push({ label: "Concurrency", value: String(this.concurrency) });
80
+ }
81
+ return rows.length > 0 ? rows : undefined;
82
+ }
70
83
  }
71
84
 
72
85
  export { TestTriggerNode } from "./TestTriggerNode";
package/src/nodes/wait.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { RunnableNodeConfig, TypeToken } from "@codemation/core";
1
+ import type { NodeInspectorSummaryRow, RunnableNodeConfig, TypeToken } from "@codemation/core";
2
2
 
3
3
  import { WaitNode } from "./WaitNode";
4
4
 
@@ -15,6 +15,12 @@ export class Wait<TItemJson = unknown> implements RunnableNodeConfig<TItemJson,
15
15
  public readonly milliseconds: number,
16
16
  public readonly id?: string,
17
17
  ) {}
18
+
19
+ inspectorSummary(): ReadonlyArray<NodeInspectorSummaryRow> {
20
+ const seconds = this.milliseconds / 1000;
21
+ const value = seconds >= 1 ? `${seconds}s` : `${this.milliseconds}ms`;
22
+ return [{ label: "Duration", value }];
23
+ }
18
24
  }
19
25
 
20
26
  export { WaitDuration } from "./WaitDurationFactory";
@@ -1,5 +1,6 @@
1
1
  import type { ChatModelConfig } from "@codemation/core";
2
2
  import { OpenAIChatModelConfig } from "../chatModels/openAiChatModelConfig";
3
+ import { CodemationChatModelConfig } from "../chatModels/CodemationChatModelConfig";
3
4
 
4
5
  export class WorkflowChatModelFactory {
5
6
  static create(model: string | ChatModelConfig): ChatModelConfig {
@@ -7,6 +8,9 @@ export class WorkflowChatModelFactory {
7
8
  return model;
8
9
  }
9
10
  const [provider, resolvedModel] = model.includes(":") ? model.split(":", 2) : ["openai", model];
11
+ if (provider === "codemation-managed") {
12
+ return new CodemationChatModelConfig("Codemation Managed", resolvedModel ?? "");
13
+ }
10
14
  if (provider !== "openai") {
11
15
  throw new Error(`Unsupported workflow().agent() model provider "${provider}".`);
12
16
  }
@@ -1,4 +1,4 @@
1
- import type { NodeDefinition, WorkflowDefinition, WorkflowNodeConnection } from "@codemation/core";
1
+ import type { McpServerResolver, NodeDefinition, WorkflowDefinition, WorkflowNodeConnection } from "@codemation/core";
2
2
  import { AgentConfigInspector, AgentConnectionNodeCollector } from "@codemation/core";
3
3
 
4
4
  import { AIAgentNode } from "../nodes/AIAgentNode";
@@ -9,7 +9,10 @@ import { ConnectionCredentialNodeConfigFactory } from "../nodes/ConnectionCreden
9
9
  * Materializes connection-owned child nodes and {@link WorkflowDefinition.connections} for AI agent nodes.
10
10
  */
11
11
  export class AIAgentConnectionWorkflowExpander {
12
- constructor(private readonly connectionCredentialNodeConfigFactory: ConnectionCredentialNodeConfigFactory) {}
12
+ constructor(
13
+ private readonly connectionCredentialNodeConfigFactory: ConnectionCredentialNodeConfigFactory,
14
+ private readonly mcpServerResolver?: McpServerResolver,
15
+ ) {}
13
16
 
14
17
  expand(workflow: WorkflowDefinition): WorkflowDefinition {
15
18
  const existingChildIds = this.collectExistingChildIds(workflow);
@@ -21,7 +24,7 @@ export class AIAgentConnectionWorkflowExpander {
21
24
  if (node.type !== AIAgentNode || !AgentConfigInspector.isAgentNodeConfig(node.config)) {
22
25
  continue;
23
26
  }
24
- for (const connectionNode of AgentConnectionNodeCollector.collect(node.id, node.config)) {
27
+ for (const connectionNode of AgentConnectionNodeCollector.collect(node.id, node.config, this.mcpServerResolver)) {
25
28
  if (!existingChildIds.has(connectionNode.nodeId)) {
26
29
  this.assertNoIdCollision(workflow, extraNodes, existingChildIds, connectionNode.nodeId);
27
30
  extraNodes.push({
package/tsconfig.json CHANGED
@@ -3,7 +3,9 @@
3
3
  "compilerOptions": {
4
4
  "lib": ["ES2022"],
5
5
  "types": ["node"],
6
- "noEmit": true
6
+ "noEmit": true,
7
+ "experimentalDecorators": true,
8
+ "emitDecoratorMetadata": true
7
9
  },
8
10
  "include": ["src/**/*.ts"]
9
11
  }