@foresthubai/workflow-core 0.4.3 → 0.4.5
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/LICENSE +202 -202
- package/NOTICE +14 -14
- package/README.md +63 -63
- package/dist/api/deployment.d.ts +74 -0
- package/dist/api/deployment.d.ts.map +1 -0
- package/dist/api/deployment.js +6 -0
- package/dist/api/deployment.js.map +1 -0
- package/dist/api/engine.d.ts +744 -0
- package/dist/api/engine.d.ts.map +1 -0
- package/dist/api/engine.js +6 -0
- package/dist/api/engine.js.map +1 -0
- package/dist/api/index.d.ts +4 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +2 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/workflow.d.ts +25 -9
- package/dist/api/workflow.d.ts.map +1 -1
- package/dist/channel/Channel.d.ts +1 -1
- package/dist/channel/Channel.d.ts.map +1 -1
- package/dist/channel/Channel.js +3 -1
- package/dist/channel/Channel.js.map +1 -1
- package/dist/channel/ChannelDefinition.d.ts.map +1 -1
- package/dist/channel/ChannelDefinition.js +24 -0
- package/dist/channel/ChannelDefinition.js.map +1 -1
- package/dist/channel/index.d.ts.map +1 -1
- package/dist/channel/index.js +2 -0
- package/dist/channel/index.js.map +1 -1
- package/dist/channel/serialization.d.ts.map +1 -1
- package/dist/channel/serialization.js +8 -0
- package/dist/channel/serialization.js.map +1 -1
- package/dist/deploy/index.d.ts +5 -1
- package/dist/deploy/index.d.ts.map +1 -1
- package/dist/deploy/index.js +4 -1
- package/dist/deploy/index.js.map +1 -1
- package/dist/deploy/inputs.d.ts +26 -0
- package/dist/deploy/inputs.d.ts.map +1 -0
- package/dist/deploy/inputs.js +4 -0
- package/dist/deploy/inputs.js.map +1 -0
- package/dist/deploy/requirements.d.ts +24 -0
- package/dist/deploy/requirements.d.ts.map +1 -1
- package/dist/deploy/requirements.js +63 -0
- package/dist/deploy/requirements.js.map +1 -1
- package/dist/deploy/spec.d.ts +27 -0
- package/dist/deploy/spec.d.ts.map +1 -0
- package/dist/deploy/spec.js +352 -0
- package/dist/deploy/spec.js.map +1 -0
- package/dist/diagnostics/__fixtures__/diagnosticFixtures.d.ts.map +1 -1
- package/dist/diagnostics/__fixtures__/diagnosticFixtures.js +2 -0
- package/dist/diagnostics/__fixtures__/diagnosticFixtures.js.map +1 -1
- package/dist/diagnostics/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics/diagnostics.js +2 -0
- package/dist/diagnostics/diagnostics.js.map +1 -1
- package/dist/diagnostics/index.d.ts.map +1 -1
- package/dist/diagnostics/index.js +2 -0
- package/dist/diagnostics/index.js.map +1 -1
- package/dist/edge/Edge.d.ts.map +1 -1
- package/dist/edge/Edge.js +2 -0
- package/dist/edge/Edge.js.map +1 -1
- package/dist/edge/EdgeDefinition.d.ts.map +1 -1
- package/dist/edge/EdgeDefinition.js +2 -0
- package/dist/edge/EdgeDefinition.js.map +1 -1
- package/dist/edge/EdgeType.d.ts.map +1 -1
- package/dist/edge/EdgeType.js +2 -0
- package/dist/edge/EdgeType.js.map +1 -1
- package/dist/edge/index.d.ts.map +1 -1
- package/dist/edge/index.js +2 -2
- package/dist/edge/index.js.map +1 -1
- package/dist/edge/serialization.d.ts.map +1 -1
- package/dist/edge/serialization.js +2 -0
- package/dist/edge/serialization.js.map +1 -1
- package/dist/expression/index.d.ts.map +1 -1
- package/dist/expression/index.js +2 -0
- package/dist/expression/index.js.map +1 -1
- package/dist/expression/parser.d.ts.map +1 -1
- package/dist/expression/parser.js +2 -0
- package/dist/expression/parser.js.map +1 -1
- package/dist/expression/types.d.ts.map +1 -1
- package/dist/expression/types.js +2 -0
- package/dist/expression/types.js.map +1 -1
- package/dist/function/FunctionDeclaration.d.ts.map +1 -1
- package/dist/function/FunctionDeclaration.js +2 -0
- package/dist/function/FunctionDeclaration.js.map +1 -1
- package/dist/function/index.d.ts.map +1 -1
- package/dist/function/index.js +2 -0
- package/dist/function/index.js.map +1 -1
- package/dist/function/serialization.d.ts.map +1 -1
- package/dist/function/serialization.js +2 -0
- package/dist/function/serialization.js.map +1 -1
- package/dist/id/index.d.ts.map +1 -1
- package/dist/id/index.js +2 -0
- package/dist/id/index.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/memory/Memory.d.ts.map +1 -1
- package/dist/memory/Memory.js +2 -0
- package/dist/memory/Memory.js.map +1 -1
- package/dist/memory/MemoryDefinition.d.ts.map +1 -1
- package/dist/memory/MemoryDefinition.js +2 -0
- package/dist/memory/MemoryDefinition.js.map +1 -1
- package/dist/memory/MemoryFileDefinition.d.ts.map +1 -1
- package/dist/memory/MemoryFileDefinition.js +2 -0
- package/dist/memory/MemoryFileDefinition.js.map +1 -1
- package/dist/memory/MemoryRegistry.d.ts.map +1 -1
- package/dist/memory/MemoryRegistry.js +2 -0
- package/dist/memory/MemoryRegistry.js.map +1 -1
- package/dist/memory/VectorDatabaseDefinition.d.ts.map +1 -1
- package/dist/memory/VectorDatabaseDefinition.js +2 -0
- package/dist/memory/VectorDatabaseDefinition.js.map +1 -1
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +2 -0
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/serialization.d.ts.map +1 -1
- package/dist/memory/serialization.js +2 -0
- package/dist/memory/serialization.js.map +1 -1
- package/dist/migration/index.d.ts.map +1 -1
- package/dist/migration/index.js +2 -0
- package/dist/migration/index.js.map +1 -1
- package/dist/migration/migrate.d.ts.map +1 -1
- package/dist/migration/migrate.js +2 -0
- package/dist/migration/migrate.js.map +1 -1
- package/dist/migration/migrations.d.ts.map +1 -1
- package/dist/migration/migrations.js +2 -0
- package/dist/migration/migrations.js.map +1 -1
- package/dist/migration/version.d.ts.map +1 -1
- package/dist/migration/version.js +2 -0
- package/dist/migration/version.js.map +1 -1
- package/dist/model/LLMModelDefinition.d.ts.map +1 -1
- package/dist/model/LLMModelDefinition.js +2 -0
- package/dist/model/LLMModelDefinition.js.map +1 -1
- package/dist/model/Model.d.ts.map +1 -1
- package/dist/model/Model.js +2 -13
- package/dist/model/Model.js.map +1 -1
- package/dist/model/ModelDefinition.d.ts.map +1 -1
- package/dist/model/ModelDefinition.js +2 -0
- package/dist/model/ModelDefinition.js.map +1 -1
- package/dist/model/ModelRegistry.d.ts.map +1 -1
- package/dist/model/ModelRegistry.js +2 -0
- package/dist/model/ModelRegistry.js.map +1 -1
- package/dist/model/index.d.ts.map +1 -1
- package/dist/model/index.js +2 -0
- package/dist/model/index.js.map +1 -1
- package/dist/model/serialization.d.ts.map +1 -1
- package/dist/model/serialization.js +2 -0
- package/dist/model/serialization.js.map +1 -1
- package/dist/node/AgentNode.d.ts.map +1 -1
- package/dist/node/AgentNode.js +2 -0
- package/dist/node/AgentNode.js.map +1 -1
- package/dist/node/DataNode.d.ts.map +1 -1
- package/dist/node/DataNode.js +2 -0
- package/dist/node/DataNode.js.map +1 -1
- package/dist/node/FunctionNode.d.ts.map +1 -1
- package/dist/node/FunctionNode.js +2 -0
- package/dist/node/FunctionNode.js.map +1 -1
- package/dist/node/InputNode.d.ts.map +1 -1
- package/dist/node/InputNode.js +2 -0
- package/dist/node/InputNode.js.map +1 -1
- package/dist/node/LogicNode.d.ts.map +1 -1
- package/dist/node/LogicNode.js +2 -0
- package/dist/node/LogicNode.js.map +1 -1
- package/dist/node/MqttNode.d.ts.map +1 -1
- package/dist/node/MqttNode.js +2 -0
- package/dist/node/MqttNode.js.map +1 -1
- package/dist/node/Node.d.ts.map +1 -1
- package/dist/node/Node.js +2 -7
- package/dist/node/Node.js.map +1 -1
- package/dist/node/NodeDefinition.d.ts.map +1 -1
- package/dist/node/NodeDefinition.js +2 -0
- package/dist/node/NodeDefinition.js.map +1 -1
- package/dist/node/NodeRegistry.d.ts.map +1 -1
- package/dist/node/NodeRegistry.js +2 -0
- package/dist/node/NodeRegistry.js.map +1 -1
- package/dist/node/OutputNode.d.ts.map +1 -1
- package/dist/node/OutputNode.js +4 -2
- package/dist/node/OutputNode.js.map +1 -1
- package/dist/node/ToolNode.d.ts.map +1 -1
- package/dist/node/ToolNode.js +2 -0
- package/dist/node/ToolNode.js.map +1 -1
- package/dist/node/TriggerNode.d.ts.map +1 -1
- package/dist/node/TriggerNode.js +2 -0
- package/dist/node/TriggerNode.js.map +1 -1
- package/dist/node/constants.d.ts.map +1 -1
- package/dist/node/constants.js +2 -0
- package/dist/node/constants.js.map +1 -1
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +2 -0
- package/dist/node/index.js.map +1 -1
- package/dist/node/methods.d.ts.map +1 -1
- package/dist/node/methods.js +2 -0
- package/dist/node/methods.js.map +1 -1
- package/dist/node/serialization.d.ts.map +1 -1
- package/dist/node/serialization.js +33 -13
- package/dist/node/serialization.js.map +1 -1
- package/dist/parameter/OutputParameter.d.ts.map +1 -1
- package/dist/parameter/OutputParameter.js +2 -0
- package/dist/parameter/OutputParameter.js.map +1 -1
- package/dist/parameter/Parameter.d.ts.map +1 -1
- package/dist/parameter/Parameter.js +2 -0
- package/dist/parameter/Parameter.js.map +1 -1
- package/dist/parameter/index.d.ts.map +1 -1
- package/dist/parameter/index.js +2 -0
- package/dist/parameter/index.js.map +1 -1
- package/dist/variable/Variable.d.ts.map +1 -1
- package/dist/variable/Variable.js +2 -0
- package/dist/variable/Variable.js.map +1 -1
- package/dist/variable/index.d.ts.map +1 -1
- package/dist/variable/index.js +2 -3
- package/dist/variable/index.js.map +1 -1
- package/dist/variable/operations.d.ts.map +1 -1
- package/dist/variable/operations.js +2 -0
- package/dist/variable/operations.js.map +1 -1
- package/dist/workflow/Workflow.d.ts.map +1 -1
- package/dist/workflow/Workflow.js +2 -0
- package/dist/workflow/Workflow.js.map +1 -1
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/index.js +2 -0
- package/dist/workflow/index.js.map +1 -1
- package/dist/workflow/serialization.d.ts.map +1 -1
- package/dist/workflow/serialization.js +2 -4
- package/dist/workflow/serialization.js.map +1 -1
- package/package.json +2 -2
- package/src/api/deployment.ts +74 -0
- package/src/api/engine.ts +744 -0
- package/src/api/index.ts +29 -11
- package/src/api/workflow.ts +25 -9
- package/src/channel/Channel.ts +14 -11
- package/src/channel/ChannelDefinition.ts +101 -76
- package/src/channel/index.ts +9 -6
- package/src/channel/serialization.ts +77 -68
- package/src/deploy/index.ts +17 -1
- package/src/deploy/inputs.ts +44 -0
- package/src/deploy/requirements.test.ts +64 -61
- package/src/deploy/requirements.ts +159 -41
- package/src/deploy/spec.test.ts +227 -0
- package/src/deploy/spec.ts +397 -0
- package/src/diagnostics/__fixtures__/diagnosticFixtures.ts +161 -158
- package/src/diagnostics/diagnostics.test.ts +881 -878
- package/src/diagnostics/diagnostics.ts +939 -936
- package/src/diagnostics/index.ts +14 -11
- package/src/edge/Edge.ts +26 -23
- package/src/edge/EdgeDefinition.ts +48 -45
- package/src/edge/EdgeType.ts +22 -19
- package/src/edge/index.ts +11 -8
- package/src/edge/serialization.ts +86 -83
- package/src/expression/index.ts +7 -4
- package/src/expression/parser.ts +365 -362
- package/src/expression/types.ts +33 -30
- package/src/function/FunctionDeclaration.ts +57 -54
- package/src/function/index.ts +6 -3
- package/src/function/serialization.ts +43 -40
- package/src/globals.d.ts +12 -9
- package/src/id/index.ts +11 -8
- package/src/index.ts +25 -22
- package/src/memory/Memory.ts +18 -15
- package/src/memory/MemoryDefinition.ts +19 -16
- package/src/memory/MemoryFileDefinition.ts +40 -37
- package/src/memory/MemoryRegistry.ts +38 -35
- package/src/memory/VectorDatabaseDefinition.ts +24 -21
- package/src/memory/index.ts +11 -8
- package/src/memory/serialization.ts +50 -47
- package/src/migration/index.ts +7 -4
- package/src/migration/migrate.test.ts +47 -44
- package/src/migration/migrate.ts +61 -58
- package/src/migration/migrations.ts +27 -24
- package/src/migration/version.ts +12 -9
- package/src/model/LLMModelDefinition.ts +15 -12
- package/src/model/Model.ts +42 -39
- package/src/model/ModelDefinition.ts +18 -15
- package/src/model/ModelRegistry.ts +36 -33
- package/src/model/index.ts +10 -7
- package/src/model/serialization.ts +33 -30
- package/src/node/AgentNode.ts +85 -82
- package/src/node/DataNode.ts +44 -41
- package/src/node/FunctionNode.ts +79 -76
- package/src/node/InputNode.ts +188 -185
- package/src/node/LogicNode.ts +36 -33
- package/src/node/MqttNode.ts +130 -127
- package/src/node/Node.ts +64 -61
- package/src/node/NodeDefinition.ts +40 -37
- package/src/node/NodeRegistry.ts +88 -85
- package/src/node/OutputNode.ts +90 -87
- package/src/node/ToolNode.ts +35 -32
- package/src/node/TriggerNode.ts +275 -272
- package/src/node/constants.ts +19 -16
- package/src/node/index.ts +29 -26
- package/src/node/methods.ts +281 -278
- package/src/node/serialization.test.ts +51 -0
- package/src/node/serialization.ts +565 -544
- package/src/parameter/OutputParameter.ts +71 -68
- package/src/parameter/Parameter.ts +246 -243
- package/src/parameter/index.ts +36 -33
- package/src/variable/Variable.ts +13 -10
- package/src/variable/index.ts +19 -16
- package/src/variable/operations.ts +109 -106
- package/src/workflow/Workflow.ts +44 -41
- package/src/workflow/index.ts +6 -3
- package/src/workflow/serialization.test.ts +243 -240
- package/src/workflow/serialization.ts +245 -242
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (c) 2026 ForestHub.
|
|
3
|
+
|
|
4
|
+
import type { MemoryDefinition } from "./MemoryDefinition";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* RAG knowledge base referenced from Retriever nodes. Only descriptive config
|
|
8
|
+
* lives here; the backend collection it binds to is supplied at deploy time.
|
|
9
|
+
*/
|
|
10
|
+
export const VectorDatabaseDefinition: MemoryDefinition = {
|
|
11
|
+
type: "VectorDatabase",
|
|
12
|
+
label: "Vector Database",
|
|
13
|
+
description: "RAG knowledge base that Retriever nodes can query",
|
|
14
|
+
parameters: [
|
|
15
|
+
{
|
|
16
|
+
id: "description",
|
|
17
|
+
label: "Description",
|
|
18
|
+
description: "What this knowledge base contains",
|
|
19
|
+
type: "string",
|
|
20
|
+
multiline: true,
|
|
21
|
+
optional: true,
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
};
|
package/src/memory/index.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
8
|
-
export
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (c) 2026 ForestHub.
|
|
3
|
+
|
|
4
|
+
export type { MemoryType, Memory, MemoryRef } from "./Memory";
|
|
5
|
+
export { ALL_MEMORY_TYPES } from "./Memory";
|
|
6
|
+
export type { MemoryDefinition } from "./MemoryDefinition";
|
|
7
|
+
export { MemoryFileDefinition } from "./MemoryFileDefinition";
|
|
8
|
+
export { VectorDatabaseDefinition } from "./VectorDatabaseDefinition";
|
|
9
|
+
export { MemoryRegistry } from "./MemoryRegistry";
|
|
10
|
+
export { serialize, deserialize } from "./serialization";
|
|
11
|
+
export type { ApiMemory } from "./serialization";
|
|
@@ -1,47 +1,50 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (api.
|
|
44
|
-
break;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (c) 2026 ForestHub.
|
|
3
|
+
|
|
4
|
+
import type { Schemas } from "../api";
|
|
5
|
+
import type { Memory } from "./Memory";
|
|
6
|
+
|
|
7
|
+
export type ApiMemory = Schemas["Memory"];
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Serialize a domain Memory to the API discriminated-union shape.
|
|
11
|
+
* MemoryFile drops `maxSizeBytes` when unset (absent and null both mean "unlimited").
|
|
12
|
+
*/
|
|
13
|
+
export function serialize(mem: Memory): ApiMemory {
|
|
14
|
+
const { id, label, type, arguments: args } = mem;
|
|
15
|
+
switch (type) {
|
|
16
|
+
case "MemoryFile":
|
|
17
|
+
return {
|
|
18
|
+
type,
|
|
19
|
+
id,
|
|
20
|
+
label,
|
|
21
|
+
description: (args.description as string) ?? "",
|
|
22
|
+
content: (args.content as string) ?? "",
|
|
23
|
+
...(args.maxSizeBytes != null ? { maxSizeBytes: args.maxSizeBytes as number } : {}),
|
|
24
|
+
};
|
|
25
|
+
case "VectorDatabase":
|
|
26
|
+
return {
|
|
27
|
+
type,
|
|
28
|
+
id,
|
|
29
|
+
label,
|
|
30
|
+
...(args.description != null ? { description: args.description as string } : {}),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Convert an API Memory into a domain Memory. */
|
|
36
|
+
export function deserialize(api: ApiMemory): Memory {
|
|
37
|
+
const { id, label, type } = api;
|
|
38
|
+
const args: Record<string, unknown> = {};
|
|
39
|
+
switch (type) {
|
|
40
|
+
case "MemoryFile":
|
|
41
|
+
args.description = api.description ?? "";
|
|
42
|
+
args.content = api.content ?? "";
|
|
43
|
+
if (api.maxSizeBytes != null) args.maxSizeBytes = api.maxSizeBytes;
|
|
44
|
+
break;
|
|
45
|
+
case "VectorDatabase":
|
|
46
|
+
if (api.description != null) args.description = api.description;
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
return { id, label, type, arguments: args };
|
|
50
|
+
}
|
package/src/migration/index.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (c) 2026 ForestHub.
|
|
3
|
+
|
|
4
|
+
export { CURRENT_SCHEMA_VERSION, BASELINE_SCHEMA_VERSION } from "./version";
|
|
5
|
+
export { migrate, readSchemaVersion } from "./migrate";
|
|
6
|
+
export { MIGRATIONS } from "./migrations";
|
|
7
|
+
export type { Migration } from "./migrations";
|
|
@@ -1,44 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
expect(readSchemaVersion({
|
|
15
|
-
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (c) 2026 ForestHub.
|
|
3
|
+
|
|
4
|
+
import { describe, it, expect } from "vitest";
|
|
5
|
+
import { migrate, readSchemaVersion } from "./migrate";
|
|
6
|
+
import { CURRENT_SCHEMA_VERSION } from "./version";
|
|
7
|
+
|
|
8
|
+
describe("readSchemaVersion", () => {
|
|
9
|
+
it("reads an explicit integer version", () => {
|
|
10
|
+
expect(readSchemaVersion({ schemaVersion: 3 })).toBe(3);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it("defaults missing, non-integer, or out-of-range to the baseline", () => {
|
|
14
|
+
expect(readSchemaVersion({})).toBe(1);
|
|
15
|
+
expect(readSchemaVersion({ schemaVersion: 1.5 })).toBe(1);
|
|
16
|
+
expect(readSchemaVersion({ schemaVersion: 0 })).toBe(1);
|
|
17
|
+
expect(readSchemaVersion({ schemaVersion: "2" })).toBe(1);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe("migrate", () => {
|
|
22
|
+
it("stamps the current version on a baseline document", () => {
|
|
23
|
+
const out = migrate({ nodes: [], edges: [] });
|
|
24
|
+
expect(out.schemaVersion).toBe(CURRENT_SCHEMA_VERSION);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("passes through a document already at the current version", () => {
|
|
28
|
+
const doc = { schemaVersion: CURRENT_SCHEMA_VERSION, nodes: [] };
|
|
29
|
+
expect(migrate(doc).schemaVersion).toBe(CURRENT_SCHEMA_VERSION);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("does not mutate its input", () => {
|
|
33
|
+
const doc: Record<string, unknown> = { nodes: [] };
|
|
34
|
+
migrate(doc);
|
|
35
|
+
expect("schemaVersion" in doc).toBe(false);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("rejects a document newer than this build supports", () => {
|
|
39
|
+
expect(() => migrate({ schemaVersion: CURRENT_SCHEMA_VERSION + 1 })).toThrow(/newer than this build/);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("rejects a non-object document", () => {
|
|
43
|
+
expect(() => migrate(null)).toThrow(/must be a JSON object/);
|
|
44
|
+
expect(() => migrate([])).toThrow(/must be a JSON object/);
|
|
45
|
+
expect(() => migrate(42)).toThrow(/must be a JSON object/);
|
|
46
|
+
});
|
|
47
|
+
});
|
package/src/migration/migrate.ts
CHANGED
|
@@ -1,58 +1,61 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (
|
|
17
|
-
throw new Error(`[migration]
|
|
18
|
-
}
|
|
19
|
-
byFrom.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
*
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (c) 2026 ForestHub.
|
|
3
|
+
|
|
4
|
+
import type { ApiWorkflow } from "../workflow/Workflow";
|
|
5
|
+
import { MIGRATIONS, type Migration } from "./migrations";
|
|
6
|
+
import { BASELINE_SCHEMA_VERSION, CURRENT_SCHEMA_VERSION } from "./version";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Index the registry by `from` and assert it forms a contiguous chain over
|
|
10
|
+
* [BASELINE_SCHEMA_VERSION, CURRENT_SCHEMA_VERSION). A gap or duplicate is a
|
|
11
|
+
* programming error, so it throws at module load rather than on first use.
|
|
12
|
+
*/
|
|
13
|
+
function buildChain(migrations: readonly Migration[]): ReadonlyMap<number, Migration> {
|
|
14
|
+
const byFrom = new Map<number, Migration>();
|
|
15
|
+
for (const m of migrations) {
|
|
16
|
+
if (!Number.isInteger(m.from) || m.from < BASELINE_SCHEMA_VERSION || m.from >= CURRENT_SCHEMA_VERSION) {
|
|
17
|
+
throw new Error(`[migration] from must be an integer in [${BASELINE_SCHEMA_VERSION}, ${CURRENT_SCHEMA_VERSION}), got ${m.from}`);
|
|
18
|
+
}
|
|
19
|
+
if (byFrom.has(m.from)) {
|
|
20
|
+
throw new Error(`[migration] duplicate migration from ${m.from}`);
|
|
21
|
+
}
|
|
22
|
+
byFrom.set(m.from, m);
|
|
23
|
+
}
|
|
24
|
+
for (let v = BASELINE_SCHEMA_VERSION; v < CURRENT_SCHEMA_VERSION; v++) {
|
|
25
|
+
if (!byFrom.has(v)) throw new Error(`[migration] missing migration from ${v} -> ${v + 1}`);
|
|
26
|
+
}
|
|
27
|
+
return byFrom;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const CHAIN = buildChain(MIGRATIONS);
|
|
31
|
+
|
|
32
|
+
/** Read the schema version, defaulting absent/invalid to the baseline. */
|
|
33
|
+
export function readSchemaVersion(doc: Record<string, unknown>): number {
|
|
34
|
+
const v = doc.schemaVersion;
|
|
35
|
+
return typeof v === "number" && Number.isInteger(v) && v >= BASELINE_SCHEMA_VERSION ? v : BASELINE_SCHEMA_VERSION;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Upgrade a raw, parsed workflow document to CURRENT_SCHEMA_VERSION and return
|
|
40
|
+
* it as the current {@link ApiWorkflow}, ready for `deserialize`. Runs on
|
|
41
|
+
* untyped JSON so each migration stays pinned to the shape it was written for.
|
|
42
|
+
* Throws on a non-object, or a version newer than this build supports.
|
|
43
|
+
*/
|
|
44
|
+
export function migrate(raw: unknown): ApiWorkflow {
|
|
45
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
46
|
+
throw new Error("[migration] workflow document must be a JSON object");
|
|
47
|
+
}
|
|
48
|
+
let doc: Record<string, unknown> = { ...(raw as Record<string, unknown>) };
|
|
49
|
+
|
|
50
|
+
const version = readSchemaVersion(doc);
|
|
51
|
+
if (version > CURRENT_SCHEMA_VERSION) {
|
|
52
|
+
throw new Error(`[migration] schemaVersion ${version} is newer than this build supports (${CURRENT_SCHEMA_VERSION})`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
for (let v = version; v < CURRENT_SCHEMA_VERSION; v++) {
|
|
56
|
+
doc = CHAIN.get(v)!.migrate(doc); // non-null: buildChain covers every v in range
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
doc.schemaVersion = CURRENT_SCHEMA_VERSION;
|
|
60
|
+
return doc as ApiWorkflow;
|
|
61
|
+
}
|
|
@@ -1,24 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
*
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (c) 2026 ForestHub.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A single-step upgrade of the persisted workflow format, from `from` to
|
|
6
|
+
* `from + 1`. Operates on the raw parsed document, never the domain types.
|
|
7
|
+
* Forward-only: there is no down-path.
|
|
8
|
+
*
|
|
9
|
+
* A shipped migration is immutable — saved files depend on its exact behaviour.
|
|
10
|
+
* Express the next change as a new migration, never an edit to an old one.
|
|
11
|
+
*/
|
|
12
|
+
export interface Migration {
|
|
13
|
+
/** Schema version this migration expects as input. Produces `from + 1`. */
|
|
14
|
+
readonly from: number;
|
|
15
|
+
/** Pure transform on the raw document; must not mutate its input. */
|
|
16
|
+
migrate(doc: Record<string, unknown>): Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Ordered registry of single-step format migrations. To change the format:
|
|
21
|
+
* bump CURRENT_SCHEMA_VERSION, append one migration with `from` set to the
|
|
22
|
+
* previous value, and reconcile serialize/deserialize. {@link migrate} asserts
|
|
23
|
+
* at load that the chain is contiguous over [BASELINE, CURRENT).
|
|
24
|
+
*/
|
|
25
|
+
export const MIGRATIONS: readonly Migration[] = [
|
|
26
|
+
// First entry will be `{ from: 1, migrate: (doc) => ... }`.
|
|
27
|
+
];
|
package/src/migration/version.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export const
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (c) 2026 ForestHub.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Persisted-format version this build reads and writes. A plain monotonic
|
|
6
|
+
* integer, decoupled from the contract/package semver. Bump only when the
|
|
7
|
+
* serialized {@link ApiWorkflow} shape changes, adding a matching migration.
|
|
8
|
+
*/
|
|
9
|
+
export const CURRENT_SCHEMA_VERSION = 1;
|
|
10
|
+
|
|
11
|
+
/** Version assumed for documents that carry no `schemaVersion`. */
|
|
12
|
+
export const BASELINE_SCHEMA_VERSION = 1;
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (c) 2026 ForestHub.
|
|
3
|
+
|
|
4
|
+
import type { ModelDefinition } from "./ModelDefinition";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A declared custom/self-hosted LLM model.
|
|
8
|
+
* Capabilities default to ["chat"] on serialize; a capability editor can be added later.
|
|
9
|
+
*/
|
|
10
|
+
export const LLMModelDefinition: ModelDefinition = {
|
|
11
|
+
type: "LLMModel",
|
|
12
|
+
label: "Custom LLM Model",
|
|
13
|
+
description: "A self-hosted or custom LLM the llmproxy doesn't ship by default",
|
|
14
|
+
parameters: [],
|
|
15
|
+
};
|
package/src/model/Model.ts
CHANGED
|
@@ -1,39 +1,42 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
// `
|
|
13
|
-
//
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (c) 2026 ForestHub.
|
|
3
|
+
|
|
4
|
+
// Domain Model — covers two distinct things that share a picker:
|
|
5
|
+
// 1. The STATIC catalog (ModelInfo[]): the set of models the llmproxy already
|
|
6
|
+
// supports. Supplied to the editor as data (props), not declared per-workflow.
|
|
7
|
+
// A node simply stores the chosen catalog ModelID directly.
|
|
8
|
+
// 2. DECLARED custom models (Model): self-hosted / custom models the
|
|
9
|
+
// llmproxy doesn't ship. These are channel-like — declared in the workflow,
|
|
10
|
+
// referenced by id from nodes, and mapped to an llmproxy provider at deploy.
|
|
11
|
+
//
|
|
12
|
+
// A node's `model` field is always just a ModelID string either way; static ids
|
|
13
|
+
// resolve via the catalog (no mapping), custom ids via a declared Model.
|
|
14
|
+
//
|
|
15
|
+
// `type` is the api discriminator; new model families (e.g. future YOLO/ONNX
|
|
16
|
+
// variants) register their own definition in ModelRegistry, mirroring nodes.
|
|
17
|
+
|
|
18
|
+
import type { Schemas } from "../api";
|
|
19
|
+
|
|
20
|
+
/** A capability a model supports (chat, embedding, vision, ...). From the api. */
|
|
21
|
+
export type ModelCapability = Schemas["ModelCapability"];
|
|
22
|
+
|
|
23
|
+
export type ModelType = "LLMModel";
|
|
24
|
+
|
|
25
|
+
export const ALL_MODEL_TYPES: ModelType[] = ["LLMModel"];
|
|
26
|
+
|
|
27
|
+
export interface Model {
|
|
28
|
+
id: string;
|
|
29
|
+
label: string;
|
|
30
|
+
type: ModelType;
|
|
31
|
+
arguments: Record<string, unknown>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* One entry in the static model catalog handed to the builder via props. The
|
|
36
|
+
* embedder maps the llmproxy's richer ModelInfo down to this minimal shape.
|
|
37
|
+
*/
|
|
38
|
+
export interface ModelInfo {
|
|
39
|
+
id: string;
|
|
40
|
+
label: string;
|
|
41
|
+
capabilities: ModelCapability[];
|
|
42
|
+
}
|
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
*
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (c) 2026 ForestHub.
|
|
3
|
+
|
|
4
|
+
import type { Parameter } from "../parameter";
|
|
5
|
+
import type { ModelType } from "./Model";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Static, per-type metadata for a declared (custom) model variant. Mirrors
|
|
9
|
+
* MemoryDefinition / NodeDefinition: one definition object per ModelType,
|
|
10
|
+
* registered in ModelRegistry. `label` is a top-level instance field (edited
|
|
11
|
+
* like a channel label), so it is never a parameter here.
|
|
12
|
+
*/
|
|
13
|
+
export interface ModelDefinition {
|
|
14
|
+
type: ModelType;
|
|
15
|
+
label: string;
|
|
16
|
+
description: string;
|
|
17
|
+
parameters: Parameter[];
|
|
18
|
+
}
|