@nodetool-ai/node-sdk 0.7.0-rc.23 → 0.8.2

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 (158) hide show
  1. package/README.md +34 -0
  2. package/dist/.nodetool-build-stamp +1 -0
  3. package/dist/base-node.d.ts +285 -14
  4. package/dist/base-node.d.ts.map +1 -1
  5. package/dist/base-node.js +359 -49
  6. package/dist/base-node.js.map +1 -1
  7. package/dist/class-name-to-title.d.ts +26 -0
  8. package/dist/class-name-to-title.d.ts.map +1 -0
  9. package/dist/class-name-to-title.js +59 -0
  10. package/dist/class-name-to-title.js.map +1 -0
  11. package/dist/code-analysis.d.ts +234 -0
  12. package/dist/code-analysis.d.ts.map +1 -0
  13. package/dist/code-analysis.js +919 -0
  14. package/dist/code-analysis.js.map +1 -0
  15. package/dist/code-body.d.ts +61 -0
  16. package/dist/code-body.d.ts.map +1 -0
  17. package/dist/code-body.js +288 -0
  18. package/dist/code-body.js.map +1 -0
  19. package/dist/code-node-validation.d.ts +67 -0
  20. package/dist/code-node-validation.d.ts.map +1 -0
  21. package/dist/code-node-validation.js +540 -0
  22. package/dist/code-node-validation.js.map +1 -0
  23. package/dist/content-card.d.ts +30 -0
  24. package/dist/content-card.d.ts.map +1 -0
  25. package/dist/content-card.js +68 -0
  26. package/dist/content-card.js.map +1 -0
  27. package/dist/correlation-validation.d.ts +19 -0
  28. package/dist/correlation-validation.d.ts.map +1 -0
  29. package/dist/correlation-validation.js +101 -0
  30. package/dist/correlation-validation.js.map +1 -0
  31. package/dist/cost-estimate.d.ts +244 -0
  32. package/dist/cost-estimate.d.ts.map +1 -0
  33. package/dist/cost-estimate.js +637 -0
  34. package/dist/cost-estimate.js.map +1 -0
  35. package/dist/decorators.d.ts.map +1 -1
  36. package/dist/decorators.js +4 -1
  37. package/dist/decorators.js.map +1 -1
  38. package/dist/docs/nodes.d.ts.map +1 -1
  39. package/dist/docs/nodes.js +3 -2
  40. package/dist/docs/nodes.js.map +1 -1
  41. package/dist/docs/overview.d.ts.map +1 -1
  42. package/dist/docs/overview.js +4 -3
  43. package/dist/docs/overview.js.map +1 -1
  44. package/dist/docs/workflows.d.ts.map +1 -1
  45. package/dist/docs/workflows.js +10 -9
  46. package/dist/docs/workflows.js.map +1 -1
  47. package/dist/field-classification.d.ts +31 -0
  48. package/dist/field-classification.d.ts.map +1 -0
  49. package/dist/field-classification.js +58 -0
  50. package/dist/field-classification.js.map +1 -0
  51. package/dist/graph-validation.d.ts +239 -0
  52. package/dist/graph-validation.d.ts.map +1 -0
  53. package/dist/graph-validation.js +1174 -0
  54. package/dist/graph-validation.js.map +1 -0
  55. package/dist/index.d.ts +27 -2
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +29 -1
  58. package/dist/index.js.map +1 -1
  59. package/dist/js-script-link.d.ts +53 -0
  60. package/dist/js-script-link.d.ts.map +1 -0
  61. package/dist/js-script-link.js +58 -0
  62. package/dist/js-script-link.js.map +1 -0
  63. package/dist/js-script-materialize.d.ts +52 -0
  64. package/dist/js-script-materialize.d.ts.map +1 -0
  65. package/dist/js-script-materialize.js +24 -0
  66. package/dist/js-script-materialize.js.map +1 -0
  67. package/dist/manifest-node-values.d.ts +106 -0
  68. package/dist/manifest-node-values.d.ts.map +1 -0
  69. package/dist/manifest-node-values.js +195 -0
  70. package/dist/manifest-node-values.js.map +1 -0
  71. package/dist/metadata.d.ts +75 -3
  72. package/dist/metadata.d.ts.map +1 -1
  73. package/dist/metadata.js +132 -49
  74. package/dist/metadata.js.map +1 -1
  75. package/dist/node-metadata.d.ts.map +1 -1
  76. package/dist/node-metadata.js +61 -56
  77. package/dist/node-metadata.js.map +1 -1
  78. package/dist/node-type-inventory.d.ts +51 -0
  79. package/dist/node-type-inventory.d.ts.map +1 -0
  80. package/dist/node-type-inventory.js +121 -0
  81. package/dist/node-type-inventory.js.map +1 -0
  82. package/dist/nodes/test-nodes.d.ts +77 -30
  83. package/dist/nodes/test-nodes.d.ts.map +1 -1
  84. package/dist/nodes/test-nodes.js +2 -34
  85. package/dist/nodes/test-nodes.js.map +1 -1
  86. package/dist/pack-loader.d.ts +202 -0
  87. package/dist/pack-loader.d.ts.map +1 -0
  88. package/dist/pack-loader.js +529 -0
  89. package/dist/pack-loader.js.map +1 -0
  90. package/dist/port-types.d.ts +15 -0
  91. package/dist/port-types.d.ts.map +1 -0
  92. package/dist/port-types.js +72 -0
  93. package/dist/port-types.js.map +1 -0
  94. package/dist/pricing-bundle.d.ts +83 -0
  95. package/dist/pricing-bundle.d.ts.map +1 -0
  96. package/dist/pricing-bundle.js +82 -0
  97. package/dist/pricing-bundle.js.map +1 -0
  98. package/dist/pricing-params.d.ts +59 -0
  99. package/dist/pricing-params.d.ts.map +1 -0
  100. package/dist/pricing-params.js +282 -0
  101. package/dist/pricing-params.js.map +1 -0
  102. package/dist/python-package-scan.d.ts +8 -0
  103. package/dist/python-package-scan.d.ts.map +1 -1
  104. package/dist/python-package-scan.js +21 -8
  105. package/dist/python-package-scan.js.map +1 -1
  106. package/dist/registry.d.ts +105 -2
  107. package/dist/registry.d.ts.map +1 -1
  108. package/dist/registry.js +403 -30
  109. package/dist/registry.js.map +1 -1
  110. package/dist/sandbox-bridge-packs.d.ts +39 -0
  111. package/dist/sandbox-bridge-packs.d.ts.map +1 -0
  112. package/dist/sandbox-bridge-packs.js +249 -0
  113. package/dist/sandbox-bridge-packs.js.map +1 -0
  114. package/dist/sandbox-catalog-host.d.ts +31 -0
  115. package/dist/sandbox-catalog-host.d.ts.map +1 -0
  116. package/dist/sandbox-catalog-host.js +78 -0
  117. package/dist/sandbox-catalog-host.js.map +1 -0
  118. package/dist/sandbox-module-catalog.d.ts +14 -0
  119. package/dist/sandbox-module-catalog.d.ts.map +1 -0
  120. package/dist/sandbox-module-catalog.js +402 -0
  121. package/dist/sandbox-module-catalog.js.map +1 -0
  122. package/dist/sandbox-npm-artifacts.d.ts +56 -0
  123. package/dist/sandbox-npm-artifacts.d.ts.map +1 -0
  124. package/dist/sandbox-npm-artifacts.js +17 -0
  125. package/dist/sandbox-npm-artifacts.js.map +1 -0
  126. package/dist/sandbox-pack-discovery.d.ts +93 -0
  127. package/dist/sandbox-pack-discovery.d.ts.map +1 -0
  128. package/dist/sandbox-pack-discovery.js +807 -0
  129. package/dist/sandbox-pack-discovery.js.map +1 -0
  130. package/dist/search.d.ts +29 -1
  131. package/dist/search.d.ts.map +1 -1
  132. package/dist/search.js +136 -9
  133. package/dist/search.js.map +1 -1
  134. package/dist/type-compat.d.ts +36 -0
  135. package/dist/type-compat.d.ts.map +1 -0
  136. package/dist/type-compat.js +98 -0
  137. package/dist/type-compat.js.map +1 -0
  138. package/dist/type-predicates.d.ts +25 -0
  139. package/dist/type-predicates.d.ts.map +1 -0
  140. package/dist/type-predicates.js +31 -0
  141. package/dist/type-predicates.js.map +1 -0
  142. package/dist/validation.d.ts +18 -0
  143. package/dist/validation.d.ts.map +1 -1
  144. package/dist/validation.js +70 -11
  145. package/dist/validation.js.map +1 -1
  146. package/dist/workflow-document-tools.d.ts +35 -0
  147. package/dist/workflow-document-tools.d.ts.map +1 -0
  148. package/dist/workflow-document-tools.js +402 -0
  149. package/dist/workflow-document-tools.js.map +1 -0
  150. package/dist/workflow-interface.d.ts +62 -0
  151. package/dist/workflow-interface.d.ts.map +1 -0
  152. package/dist/workflow-interface.js +351 -0
  153. package/dist/workflow-interface.js.map +1 -0
  154. package/package.json +67 -10
  155. package/dist/package-registry-client.d.ts +0 -12
  156. package/dist/package-registry-client.d.ts.map +0 -1
  157. package/dist/package-registry-client.js +0 -40
  158. package/dist/package-registry-client.js.map +0 -1
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Which output types render as a content card.
3
+ *
4
+ * A node whose primary output is one of these has something to *show* — an
5
+ * image, a video, an audio waveform, a 3D model, or text. The editor renders
6
+ * those with `ContentCardBody` (a preview-forward body) instead of the generic
7
+ * input/output layout, driven by `body: "content_card"` in the node metadata.
8
+ *
9
+ * Provider packs derive the flag from their manifest rather than declaring it
10
+ * per node, so a new model added to a manifest gets the right body for free.
11
+ * Keep this list in sync with `getContentCardVariant` in
12
+ * `web/src/components/node_types/contentCardRegistry.ts`, which maps the same
13
+ * types onto the concrete preview variant.
14
+ */
15
+ const CONTENT_CARD_OUTPUT_TYPES = new Set([
16
+ "image",
17
+ "image_mask",
18
+ "mask",
19
+ "video",
20
+ "audio",
21
+ "model_3d",
22
+ "asset_3d",
23
+ "str",
24
+ "text"
25
+ ]);
26
+ /** True when a node with this primary output type should render a content card. */
27
+ export function isContentCardOutputType(outputType) {
28
+ return outputType !== undefined && CONTENT_CARD_OUTPUT_TYPES.has(outputType);
29
+ }
30
+ /**
31
+ * Type of the output slot the editor previews — the one `getNodeMetadata`
32
+ * puts at `outputs[0]`, so the resolution order matches it: an explicit
33
+ * `metadataOutputTypes` map wins over `outputTypes`.
34
+ */
35
+ export function primaryDeclaredOutputType(nodeClass) {
36
+ const declared = nodeClass.metadataOutputTypes ?? nodeClass.outputTypes ?? {};
37
+ return Object.values(declared)[0];
38
+ }
39
+ /**
40
+ * Stamp `body = "content_card"` on a generated node class whose primary output
41
+ * is displayable. A class that already declares its own `body` keeps it —
42
+ * per-node overrides win (e.g. the "small" voice-picker bodies).
43
+ *
44
+ * Call after the class's output types are defined.
45
+ */
46
+ export function applyContentCardBody(nodeClass) {
47
+ if (nodeClass.body !== undefined) {
48
+ return;
49
+ }
50
+ if (!isContentCardOutputType(primaryDeclaredOutputType(nodeClass))) {
51
+ return;
52
+ }
53
+ Object.defineProperty(nodeClass, "body", {
54
+ value: "content_card",
55
+ configurable: true
56
+ });
57
+ }
58
+ /**
59
+ * List form of {@link applyContentCardBody}, for hand-written node packs that
60
+ * export a node array. Returns `classes` so it can wrap the array literal.
61
+ */
62
+ export function tagContentCardBodies(classes) {
63
+ for (const cls of classes) {
64
+ applyContentCardBody(cls);
65
+ }
66
+ return classes;
67
+ }
68
+ //# sourceMappingURL=content-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-card.js","sourceRoot":"","sources":["../src/content-card.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,yBAAyB,GAAwB,IAAI,GAAG,CAAC;IAC7D,OAAO;IACP,YAAY;IACZ,MAAM;IACN,OAAO;IACP,OAAO;IACP,UAAU;IACV,UAAU;IACV,KAAK;IACL,MAAM;CACP,CAAC,CAAC;AAWH,mFAAmF;AACnF,MAAM,UAAU,uBAAuB,CACrC,UAA8B;IAE9B,OAAO,UAAU,KAAK,SAAS,IAAI,yBAAyB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AAC/E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CACvC,SAA4B;IAE5B,MAAM,QAAQ,GAAG,SAAS,CAAC,mBAAmB,IAAI,SAAS,CAAC,WAAW,IAAI,EAAE,CAAC;IAC9E,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAA4B;IAC/D,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO;IACT,CAAC;IACD,IAAI,CAAC,uBAAuB,CAAC,yBAAyB,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QACnE,OAAO;IACT,CAAC;IACD,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE;QACvC,KAAK,EAAE,cAAc;QACrB,YAAY,EAAE,IAAI;KACnB,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAU;IAEV,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { InputMode, OutputCorrelation } from "@nodetool-ai/protocol";
2
+ export interface CorrelationValidationIssue {
3
+ nodeType: string;
4
+ handle?: string;
5
+ message: string;
6
+ }
7
+ export declare class CorrelationMetadataError extends Error {
8
+ readonly issues: readonly CorrelationValidationIssue[];
9
+ constructor(issues: readonly CorrelationValidationIssue[]);
10
+ }
11
+ /**
12
+ * Descriptor-level validation of `output_correlation` per docs/correlation-design.md §3.
13
+ *
14
+ * Only checks rules that depend solely on the node metadata. Graph-topology rules
15
+ * (multi-edge list source scopes, strict-prefix invocation scope, Zip constraints)
16
+ * belong to the static-correlation analyzer added in PR 3.
17
+ */
18
+ export declare function validateOutputCorrelation(nodeType: string, inputMode: InputMode | undefined, outputCorrelation: Record<string, OutputCorrelation> | undefined, declaredOutputs: readonly string[]): CorrelationValidationIssue[];
19
+ //# sourceMappingURL=correlation-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"correlation-validation.d.ts","sourceRoot":"","sources":["../src/correlation-validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1E,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,QAAQ,CAAC,MAAM,EAAE,SAAS,0BAA0B,EAAE,CAAC;IAEvD,YAAY,MAAM,EAAE,SAAS,0BAA0B,EAAE,EAexD;CACF;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,SAAS,EAChE,eAAe,EAAE,SAAS,MAAM,EAAE,GACjC,0BAA0B,EAAE,CAmF9B"}
@@ -0,0 +1,101 @@
1
+ export class CorrelationMetadataError extends Error {
2
+ issues;
3
+ constructor(issues) {
4
+ const first = issues[0];
5
+ const summary = issues.length === 1
6
+ ? `${first.nodeType}: ${first.message}`
7
+ : `${issues.length} correlation metadata issues:\n` +
8
+ issues
9
+ .map((i) => ` - ${i.nodeType}${i.handle ? `.${i.handle}` : ""}: ${i.message}`)
10
+ .join("\n");
11
+ super(summary);
12
+ this.name = "CorrelationMetadataError";
13
+ this.issues = issues;
14
+ }
15
+ }
16
+ /**
17
+ * Descriptor-level validation of `output_correlation` per docs/correlation-design.md §3.
18
+ *
19
+ * Only checks rules that depend solely on the node metadata. Graph-topology rules
20
+ * (multi-edge list source scopes, strict-prefix invocation scope, Zip constraints)
21
+ * belong to the static-correlation analyzer added in PR 3.
22
+ */
23
+ export function validateOutputCorrelation(nodeType, inputMode, outputCorrelation, declaredOutputs) {
24
+ if (!outputCorrelation)
25
+ return [];
26
+ const issues = [];
27
+ const groupSources = new Map();
28
+ const declaredOutputSet = new Set(declaredOutputs);
29
+ for (const [handle, corr] of Object.entries(outputCorrelation)) {
30
+ if (!corr.source) {
31
+ issues.push({
32
+ nodeType,
33
+ handle,
34
+ message: `output "${handle}" must declare an explicit source (use "__execution__" or an input handle name)`
35
+ });
36
+ continue;
37
+ }
38
+ if (corr.kind === "forward") {
39
+ if (corr.source === "__execution__") {
40
+ issues.push({
41
+ nodeType,
42
+ handle,
43
+ message: `forward output "${handle}" cannot use source "__execution__"; specify an input handle`
44
+ });
45
+ }
46
+ }
47
+ if (corr.kind === "aggregate") {
48
+ if (!corr.collapse) {
49
+ issues.push({
50
+ nodeType,
51
+ handle,
52
+ message: `aggregate output "${handle}" must declare a collapse spec (e.g. "innermost")`
53
+ });
54
+ }
55
+ if (inputMode === "buffered") {
56
+ issues.push({
57
+ nodeType,
58
+ handle,
59
+ message: `aggregate output "${handle}" is not allowed on buffered nodes; set input_mode: "stream"`
60
+ });
61
+ }
62
+ }
63
+ if (corr.kind === "iteration" && corr.group) {
64
+ const existing = groupSources.get(corr.group);
65
+ if (existing !== undefined && existing !== corr.source) {
66
+ issues.push({
67
+ nodeType,
68
+ handle,
69
+ message: `iteration group "${corr.group}" has conflicting sources: "${existing}" and "${corr.source}" — handles in one group must share one source`
70
+ });
71
+ }
72
+ else {
73
+ groupSources.set(corr.group, corr.source);
74
+ }
75
+ }
76
+ if (declaredOutputSet.size > 0 && !declaredOutputSet.has(handle)) {
77
+ issues.push({
78
+ nodeType,
79
+ handle,
80
+ message: `output_correlation references handle "${handle}" not in declared outputs`
81
+ });
82
+ }
83
+ }
84
+ // Every declared output must have a correlation entry. A node may opt out
85
+ // of correlation entirely by leaving output_correlation undefined; once it
86
+ // declares any entry it has committed to the per-output contract.
87
+ // Stryker disable next-line ConditionalExpression,EqualityOperator: the guard only short-circuits an empty set; the loop body is a no-op for size 0, so size > 0 vs size >= 0 vs always-true are indistinguishable (equivalent).
88
+ if (declaredOutputSet.size > 0) {
89
+ for (const handle of declaredOutputSet) {
90
+ if (!(handle in outputCorrelation)) {
91
+ issues.push({
92
+ nodeType,
93
+ handle,
94
+ message: `declared output "${handle}" is missing a correlation entry`
95
+ });
96
+ }
97
+ }
98
+ }
99
+ return issues;
100
+ }
101
+ //# sourceMappingURL=correlation-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"correlation-validation.js","sourceRoot":"","sources":["../src/correlation-validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Pure pre-run cost estimation for a workflow graph.
3
+ *
4
+ * Walks the nodes, resolves per-node unit pricing attached to node metadata
5
+ * (`fal_unit_pricing` first, then `kie_unit_pricing`) — or, where the model
6
+ * catalogs publish a grid for the same endpoint, off that grid — multiplies by
7
+ * an expected run count, and returns a {@link WorkflowCostEstimate}. Nodes without a known
8
+ * price are still reported (cost 0, confidence "unknown") and counted, never
9
+ * hidden — the plan-before-spend view must surface uncertainty.
10
+ *
11
+ * Generic nodes (e.g. `nodetool.image.TextToImage`) carry no fixed node-type
12
+ * price — the model is chosen at runtime through a provider-model property such
13
+ * as `model`. For those, the estimator reads the selected model id from node
14
+ * data and prices it through the caller-supplied `getModelPrice` lookup.
15
+ *
16
+ * No I/O: callers supply a `getMetadata` lookup so this stays hermetic and
17
+ * usable from web, agents, and the CLI alike.
18
+ */
19
+ import type { NodeCostEstimate, WorkflowCostEstimate } from "@nodetool-ai/protocol";
20
+ import type { UnitPricing } from "./pricing-bundle.js";
21
+ /** FAL list price as attached to `NodeMetadata.fal_unit_pricing`. */
22
+ export interface FalUnitPricingLike extends UnitPricing {
23
+ endpoint_id?: string;
24
+ /** "live" means fetched from the provider this session — treated as exact. */
25
+ source?: "live" | "bundle";
26
+ }
27
+ /** kie.ai list price as attached to `NodeMetadata.kie_unit_pricing`. */
28
+ export interface KieUnitPricingLike extends UnitPricing {
29
+ model_id?: string;
30
+ /** USD conversion of the credit price, when known. Preferred over credits. */
31
+ usd_price?: number;
32
+ source?: "live" | "bundle";
33
+ }
34
+ /** A single node property as exposed by `NodeMetadata` — only the shape read here. */
35
+ export interface NodePropertyLike {
36
+ name?: string;
37
+ type?: {
38
+ type?: string;
39
+ } | null;
40
+ }
41
+ /** Minimal slice of `NodeMetadata` this estimator reads. */
42
+ export interface NodeMetadataLike {
43
+ /** The node's registered display name ("Image To Video"). */
44
+ title?: string | null;
45
+ fal_unit_pricing?: FalUnitPricingLike | null;
46
+ kie_unit_pricing?: KieUnitPricingLike | null;
47
+ /** Properties, used to find a provider-model selection on generic nodes. */
48
+ properties?: Array<NodePropertyLike | null> | null;
49
+ }
50
+ /** Price for a dynamically-selected model, as returned by `getModelPrice`. */
51
+ export interface ModelUnitPricingLike extends UnitPricing {
52
+ source?: "live" | "bundle";
53
+ }
54
+ /** A model chosen on a node via a provider-model property (e.g. `model`). */
55
+ export interface SelectedModel {
56
+ id: string;
57
+ provider: string | null;
58
+ }
59
+ /**
60
+ * What a node states about the job it is about to run, in the vocabulary the
61
+ * price catalogs bill in. Every field is optional: a missing one is priced at
62
+ * the model's base spec and recorded as an assumption, never guessed.
63
+ * `extractPricingParams` (`./pricing-params.js`) reads these off node property
64
+ * values.
65
+ */
66
+ export interface ModelPriceParams {
67
+ /** A resolution tier or a raw spelling of one ("720p", "1024x1024"). */
68
+ resolution?: string;
69
+ /** Output duration in seconds. */
70
+ seconds?: number;
71
+ withAudio?: boolean;
72
+ /** Quality tier when a provider sells several under one model id. */
73
+ tier?: string;
74
+ referenceImages?: number;
75
+ /** Duration of a video fed in, which some providers bill instead of output. */
76
+ referenceVideoSeconds?: number;
77
+ megapixels?: number;
78
+ /** Characters of text a speech job will synthesize. */
79
+ characters?: number;
80
+ }
81
+ /**
82
+ * A model price computed from {@link ModelPriceParams}. `unit_price` is the
83
+ * whole per-run figure (a per-second model comes back already multiplied by
84
+ * its duration), so `estimated_cost = unit_price × quantity` still composes.
85
+ */
86
+ export interface ModelParamPricingLike extends ModelUnitPricingLike {
87
+ /** How the figure was reached: "5 s × $0.205/s at 720p". */
88
+ breakdown?: string;
89
+ /** What was filled in because the node did not state it. */
90
+ assumptions?: string[];
91
+ /** Known-missing costs — the figure is then a lower bound. */
92
+ warnings?: string[];
93
+ /** Set instead of a price when the catalog refuses to extrapolate. */
94
+ declined?: string;
95
+ /** The duration the figure was billed for, when one applied. */
96
+ seconds?: number;
97
+ /** The rung the figure was billed at, in the catalog's own spelling. */
98
+ resolution?: string;
99
+ /** The text length the figure was billed for, when one applied. */
100
+ characters?: number;
101
+ /**
102
+ * The figure came off a published grid row, so it moves with the resolution,
103
+ * duration and audio state the node states. A flat rate leaves it unset.
104
+ */
105
+ fromGrid?: boolean;
106
+ }
107
+ /**
108
+ * A price as text. Sub-cent figures get as many decimal places as they need:
109
+ * `String(3e-7)` is `3e-7`, and a breakdown reading "$3e-7/s" is unreadable.
110
+ */
111
+ export declare const formatUsd: (usd: number) => string;
112
+ /** Extra facts a catalog row states about its own fidelity. */
113
+ export interface ScalarPriceOptions {
114
+ /** >1 means the figure is the cheapest of several published tiers. */
115
+ tierCount?: number;
116
+ }
117
+ /**
118
+ * Turn a catalog scalar into a per-run figure for the stated job.
119
+ *
120
+ * A per-second, per-minute or per-megapixel scalar times what the node states;
121
+ * a block unit times the number of blocks the duration needs. Everything else
122
+ * is already a per-run price, and a unit we cannot convert — one with no fixed
123
+ * value (credits) or a rate over something the node never states (compute
124
+ * seconds, training steps) — declines rather than passing off a per-unit number
125
+ * as the cost of a run.
126
+ *
127
+ * Every catalog scalar goes through here: the FAL/kie rows
128
+ * `@nodetool-ai/model-pricing` looks a selected model up in, and the same rows
129
+ * attached to node metadata as `fal_unit_pricing`. A 10-second clip on a
130
+ * $0.14/second endpoint costs $1.40 whichever of the two answered.
131
+ */
132
+ export declare function priceScalarUnit(price: ModelUnitPricingLike, params?: ModelPriceParams, options?: ScalarPriceOptions): ModelParamPricingLike;
133
+ /**
134
+ * A node estimate carrying the two facts the figure was reached with. They live
135
+ * here rather than in `NodeCostEstimate` (`@nodetool-ai/protocol`) so callers
136
+ * that render them — the editor's cost panel — read them off the estimate
137
+ * instead of parsing them back out of `breakdown` prose.
138
+ */
139
+ export interface NodeCostEstimateDetail extends NodeCostEstimate {
140
+ /**
141
+ * What to call this node in a cost table: the title the user gave it, else
142
+ * the node's registered title, else its class name spaced out. `node_type`
143
+ * stays the identity — a reader who needs `nodetool.video.ImageToVideo`
144
+ * still has it — but a column of dotted paths reads as one repeated prefix,
145
+ * and the four `nodetool.agents.Agent` rows of a real graph are told apart
146
+ * by their titles, not their type.
147
+ */
148
+ node_title?: string;
149
+ /** Output duration the price was multiplied by, when one applied. */
150
+ seconds?: number;
151
+ /** Rung the price was read off ("720p", "1MP"). */
152
+ resolution?: string;
153
+ }
154
+ /**
155
+ * A node type's class name, spaced: `nodetool.video.ImageToVideo` → "Image To
156
+ * Video". The last resort behind a user title and the registered metadata
157
+ * title, for a node type whose metadata a caller could not supply.
158
+ */
159
+ export declare function humanizeNodeType(nodeType: string): string;
160
+ /** {@link estimateWorkflowCost}'s result, with the detailed items. */
161
+ export interface WorkflowCostEstimateDetail extends WorkflowCostEstimate {
162
+ items: NodeCostEstimateDetail[];
163
+ }
164
+ /**
165
+ * Property `type.type` values whose value is a provider-backed model selection
166
+ * carrying a provider + model id. Kept in sync with the web `PROVIDER_MODEL_TYPES`
167
+ * list. Local model types (`llama_model`, `hf.*`) are excluded — they aren't
168
+ * priced through a provider catalog.
169
+ */
170
+ export declare const PROVIDER_MODEL_TYPES: ReadonlySet<string>;
171
+ /**
172
+ * The slice of node metadata {@link usesAiModel} reads. Structural on purpose:
173
+ * the editor's generated `NodeMetadata` and the SDK's own registry metadata are
174
+ * different types over the same fields, and both satisfy this.
175
+ */
176
+ export interface AiModelNodeMetadataLike {
177
+ type?: string;
178
+ fal_unit_pricing?: unknown;
179
+ kie_unit_pricing?: unknown;
180
+ properties?: ReadonlyArray<{
181
+ type?: {
182
+ type?: string;
183
+ } | null;
184
+ } | null> | null;
185
+ }
186
+ /**
187
+ * Whether a node type runs on an AI model — it carries provider unit pricing
188
+ * (FAL, kie) or exposes a provider-backed model property. The billable-node
189
+ * predicate: what the cost panel lists and what a pre-run estimate walks.
190
+ * Plain data and utility nodes answer false.
191
+ */
192
+ export declare function usesAiModel(metadata: AiModelNodeMetadataLike | undefined | null): boolean;
193
+ /**
194
+ * How many outputs a node is expected to produce, from its property values.
195
+ * Conservative: an absent or unreadable count is one output, so an estimate
196
+ * never over-counts a fan-out nobody asked for.
197
+ */
198
+ export declare function nodeExpectedQuantity(values: Record<string, unknown> | undefined | null): number;
199
+ export interface CostEstimateInput {
200
+ nodes: Array<{
201
+ id: string;
202
+ type: string;
203
+ data?: Record<string, unknown>;
204
+ }>;
205
+ /** Look up metadata (which may carry fal_unit_pricing / kie_unit_pricing) for a node type. */
206
+ getMetadata: (nodeType: string) => NodeMetadataLike | undefined;
207
+ /**
208
+ * Optional lookup of unit pricing for a model selected on a generic node's
209
+ * provider-model property. Returns `null`/`undefined` when the model is
210
+ * unknown. Without it, generic nodes stay "unknown".
211
+ */
212
+ getModelPrice?: (model: SelectedModel, params?: ModelPriceParams) => ModelParamPricingLike | null | undefined;
213
+ /**
214
+ * Optional per-node read of what the node states about its job (duration,
215
+ * resolution, audio). Supplied by the caller so this stays hermetic; the
216
+ * result is handed to `getModelPrice`.
217
+ */
218
+ getParams?: (node: {
219
+ id: string;
220
+ type: string;
221
+ data?: Record<string, unknown>;
222
+ }) => ModelPriceParams | undefined;
223
+ /** Optional per-node expected run count (fan-out). Defaults to 1. */
224
+ quantities?: Record<string, number>;
225
+ /**
226
+ * Optional per-node display title, keyed by node id — the name the user gave
227
+ * the node on the canvas. Falls back to the metadata title, then to the node
228
+ * type's spaced class name.
229
+ */
230
+ titles?: Record<string, string>;
231
+ /**
232
+ * Explicitly identifies graph plumbing or local utility nodes known not to
233
+ * create a billable provider request. Excluded nodes do not become
234
+ * misleading unknown-cost items.
235
+ */
236
+ isKnownNonBillable?: (node: {
237
+ id: string;
238
+ type: string;
239
+ data?: Record<string, unknown>;
240
+ }) => boolean;
241
+ currency?: string;
242
+ }
243
+ export declare function estimateWorkflowCost(input: CostEstimateInput): WorkflowCostEstimateDetail;
244
+ //# sourceMappingURL=cost-estimate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-estimate.d.ts","sourceRoot":"","sources":["../src/cost-estimate.ts"],"names":[],"mappings":"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"}